1

Angularjs アプリで使用しようとしているレスポンシブ テンプレートがあります。これは私にとって初めての Angular アプリでもあるため、今後、多くの間違いやリファクタリングが必要になることは承知しています。

angularについて十分に読んだので、DOM操作がディレクティブ内に入ることが想定されていることを知っています。

テンプレートを担当するjavascriptオブジェクトがあり、サイドメニューと基本的にテンプレートの外側のシェルのサイズが変更されます。このコードをすべてディレクティブに移動し、responsive-theme と名付けました。

まず、使用されているすべてのメソッドを追加し、最後に App オブジェクトを定義しました。コードを短くするために関数本体を削除しました。

基本的に、一番下のオブジェクトは、すべてのメソッドで使用するヘルパー オブジェクトです。

var directive = angular.module('bac.directive-manager');

directive.directive('responsiveTheme', function() {

return {
    restrict: "A",

    link: function($scope, element, attrs) {


        // IE mode
        var isRTL = false;
        var isIE8 = false;
        var isIE9 = false;
        var isIE10 = false;

        var sidebarWidth = 225;
        var sidebarCollapsedWidth = 35;

        var responsiveHandlers = [];

        // theme layout color set
        var layoutColorCodes = {

        };

        // last popep popover
        var lastPopedPopover;

        var handleInit = function() {
        };

        var handleDesktopTabletContents = function () {
        };

        var handleSidebarState = function () {
        };

        var runResponsiveHandlers = function () {
        };

        var handleResponsive = function () {
        };

        var handleResponsiveOnInit = function () {
        };

        var handleResponsiveOnResize = function () {
        };

        var handleSidebarAndContentHeight = function () {        
        };

        var handleSidebarMenu = function () {
        };

        var _calculateFixedSidebarViewportHeight = function () {
        };

        var handleFixedSidebar = function () {
        };

        var handleFixedSidebarHoverable = function () {
        };

        var handleSidebarToggler = function () {
        };

        var handleHorizontalMenu = function () {
        };

        var handleGoTop = function () {
        };

        var handlePortletTools = function () {
        };

        var handleUniform = function () {
        };

        var handleAccordions = function () {
        };

        var handleTabs = function () {
        };

        var handleScrollers = function () {
        };

        var handleTooltips = function () {
        };

        var handleDropdowns = function () {
        };

        var handleModal = function () {
        };

        var handlePopovers = function () {
        };

        var handleChoosenSelect = function () {
        };

        var handleFancybox = function () {
        };

        var handleTheme = function () {
        };

        var handleFixInputPlaceholderForIE = function () {
        };

        var handleFullScreenMode = function() {
        };

        $scope.App = {

            //main function to initiate template pages
            init: function () {

                //IMPORTANT!!!: Do not modify the core handlers call order.

                //core handlers
                handleInit();
                handleResponsiveOnResize(); // set and handle responsive    
                handleUniform();        
                handleScrollers(); // handles slim scrolling contents 
                handleResponsiveOnInit(); // handler responsive elements on page load

                //layout handlers
                handleFixedSidebar(); // handles fixed sidebar menu
                handleFixedSidebarHoverable(); // handles fixed sidebar on hover effect 
                handleSidebarMenu(); // handles main menu
                handleHorizontalMenu(); // handles horizontal menu
                handleSidebarToggler(); // handles sidebar hide/show            
                handleFixInputPlaceholderForIE(); // fixes/enables html5 placeholder attribute for IE9, IE8
                handleGoTop(); //handles scroll to top functionality in the footer
                handleTheme(); // handles style customer tool

                //ui component handlers
                handlePortletTools(); // handles portlet action bar functionality(refresh, configure, toggle, remove)
                handleDropdowns(); // handle dropdowns
                handleTabs(); // handle tabs
                handleTooltips(); // handle bootstrap tooltips
                handlePopovers(); // handles bootstrap popovers
                handleAccordions(); //handles accordions
                handleChoosenSelect(); // handles bootstrap chosen dropdowns     
                handleModal();

                $scope.App.addResponsiveHandler(handleChoosenSelect); // reinitiate chosen dropdown on main content resize. disable this line if you don't really use chosen dropdowns.
                handleFullScreenMode(); // handles full screen
            },

            fixContentHeight: function () {
                handleSidebarAndContentHeight();
            },

            setLastPopedPopover: function (el) {
                lastPopedPopover = el;
            },

            addResponsiveHandler: function (func) {
                responsiveHandlers.push(func);
            },

            // useful function to make equal height for contacts stand side by side
            setEqualHeight: function (els) {
                var tallestEl = 0;
                els = jQuery(els);
                els.each(function () {
                        var currentHeight = $(this).height();
                        if (currentHeight > tallestEl) {
                            tallestColumn = currentHeight;
                        }
                    });
                els.height(tallestEl);
            },

            // wrapper function to scroll to an element
            scrollTo: function (el, offeset) {
                pos = el ? el.offset().top : 0;
                jQuery('html,body').animate({
                        scrollTop: pos + (offeset ? offeset : 0)
                    }, 'slow');
            },

            scrollTop: function () {
                App.scrollTo();
            },

            // wrapper function to  block element(indicate loading)
            blockUI: function (ele, centerY) {
                var el = jQuery(ele); 
                el.block({
                        message: '<img src="./assets/img/ajax-loading.gif" align="">',
                        centerY: centerY !== undefined ? centerY : true,
                        css: {
                            top: '10%',
                            border: 'none',
                            padding: '2px',
                            backgroundColor: 'none'
                        },
                        overlayCSS: {
                            backgroundColor: '#000',
                            opacity: 0.05,
                            cursor: 'wait'
                        }
                    });
            },

            // wrapper function to  un-block element(finish loading)
            unblockUI: function (el) {
                jQuery(el).unblock({
                        onUnblock: function () {
                            jQuery(el).removeAttr("style");
                        }
                    });
            },

            // initializes uniform elements
            initUniform: function (els) {

                if (els) {
                    jQuery(els).each(function () {
                            if ($(this).parents(".checker").size() === 0) {
                                $(this).show();
                                $(this).uniform();
                            }
                        });
                } else {
                    handleUniform();
                }

            },

            updateUniform : function(els) {
                $.uniform.update(els);
            },

            // initializes choosen dropdowns
            initChosenSelect: function (els) {
                $(els).chosen({
                        allow_single_deselect: true
                    });
            },

            initFancybox: function () {
                handleFancybox();
            },

            getActualVal: function (ele) {
                var el = jQuery(ele);
                if (el.val() === el.attr("placeholder")) {
                    return "";
                }

                return el.val();
            },

            getURLParameter: function (paramName) {
                var searchString = window.location.search.substring(1),
                    i, val, params = searchString.split("&");

                for (i = 0; i < params.length; i++) {
                    val = params[i].split("=");
                    if (val[0] == paramName) {
                        return unescape(val[1]);
                    }
                }
                return null;
            },

            // check for device touch support
            isTouchDevice: function () {
                try {
                    document.createEvent("TouchEvent");
                    return true;
                } catch (e) {
                    return false;
                }
            },

            isIE8: function () {
                return isIE8;
            },

            isRTL: function () {
                return isRTL;
            },

            getLayoutColorCode: function (name) {
                if (layoutColorCodes[name]) {
                    return layoutColorCodes[name];
                } else {
                    return '';
                }
            }

        };

    }

};           
}); 

もともと、App.init() オブジェクト メソッドは通常の HTML ページの下部で呼び出されていましたが、ログイン ページの Login.init() などの特定のページで使用される特定の処理を実行するメソッドもあります。 .

jQueryのバックグラウンドがある場合、 stackoverflowの投稿 「Thinking in AngularJS」を読みましたか? ある意味で過去にさかのぼろうとしていることに気付きましたが、私が持っているこのテンプレートを使用したいので、このソリューションをレトロフィットする必要があります。

body タグでこのディレクティブを使用しようとしています。

<body ui-view="dashboard-shell" responsive-theme>
    <div class="page-container">
        <div class="page-sidebar nav-collapse collapse" ng-controller="SidemenuController">

            <sidemenu></sidemenu>

        </div>

        <div class="page-content" ui-view="dashboard">
        </div>
    </div>
</body>

だからここに私の問題があります。これはちょっとうまくいきます。コンソール エラーは発生しませんが、JavaScript がディレクティブに含まれているサイド メニューを使用しようとすると、コンソール内に移動して App.init() と入力するまで機能しません。その後、すべてのテンプレート javascript が機能します。これらのディレクティブでレスポンシブ テーマを行う方法を知りたいです。コンパイルセクションとリンクセクションの両方で使用してみました。コードをコンパイルしてリンクし、コントローラーから $scope.App.init() を呼び出し、すべてを定義した後、下部にも呼び出してみました。これを jsfiddle に入れてみましたが、コンソールで App.init() を呼び出さない限り、実際の例を示すことはできません。

私の最終設計では、ui-router を介してページを切り替える何らかの方法があり、ルートが切り替えられると、適切なメソッドが呼び出されるか、ディレクティブなどが再実行されます。すべてのページで実行される唯一のメソッドは App.init() メソッドであり、それ以外はすべてページ固有です。技術的には、これは単一ページのアプリであるため、アプリケーションに対して App.init() を実行する必要があるのは 1 回だけです。私はそれを ui-router 内の親テンプレートに関連付けており、切り替えるページはすべてこのシェル テンプレートを使用します。メソッドを呼び出すために他のオブジェクトにアクセスする必要があるオブジェクトがいくつかあります。

紛らわしい投稿かもしれませんが、事前に申し訳ありません。私は今、角度のある観点からあなたが物事を行う方法のいくつかをまとめようとして苦労しています. さらなる例を示すための回答が得られたら、引き続き投稿を編集します。

4

1 に答える 1

5

あなたは言っI have read enough about angular that I know DOM manipulations are suppose to go inside a directiveたが、指令の要点を逃したようだ。ディレクティブは DOM 操作を処理する必要があります。はい、ページ全体に対して 1 つのディレクティブではありません。ページの各要素 (またはセグメント) には独自のディレクティブが必要であり (その要素で DOM 操作を行う必要があると仮定)、$controllerそれらの要素とデータ (またはモデル) の間の相互作用を処理する必要があります。

あなたは 1 つの巨大なディレクティブを作成し、それを過度に実行させようとしています。ありがたいことに、コードをいくつかのディレクティブに分割するのがそれほど難しくないように、コードを設計しました。基本的に、各handle関数は独自のディレクティブにする必要があります。

したがって、次のようになります。

.directive('sidebarMenu', function(){
    return {
        template: 'path/to/sidebar/partial.html',
        link: function(scope, elem, attrs){
            // insert the code for your 'handleSidebarMenu()' function here
        }
    };
})
.directive('horizontalMenu', function(){
    return {
        template: 'path/to/horizontal/partial.html',
        link: function(scope, elem, attrs){
            // insert the code for your 'handleHorizontalMenu()' function here
        }
    };
})

ビューは次のようになります。

<body ui-view="dashboard-shell" responsive-theme>
    <div class="page-container">
        <div class="page-sidebar nav-collapse collapse">

            <horizontal-menu></horizontal-menu>

            <sidebar-menu></sidebar-menu>

        </div>

        <div class="page-content" ui-view="dashboard">
        </div>
    </div>
</body>

そして、SidebarmenuControllerコントローラー関数はサイドバーのような DOM 要素を処理するべきではないため、 は必要ありません。コントローラーは、ビューに表示するデータを処理するだけで、ビュー (または.htmlファイル) は、作成したディレクティブを使用して、そのデータの表示と操作を処理します。

それは理にかなっていますか?その巨大なディレクティブを、DOM 内の特定の要素または特定のタスクを処理する多くの小さなディレクティブに分割してみてください。

于 2013-10-18T19:33:58.587 に答える