1

を使用してメニューバーを作成しようとしていますAngularjs。以前に で同様のことを行っBackbonejsたことがありますが、angular でこれを行う方法を理解するのに苦労しています。

私のhtmlファイルには、次のメニュー プレースホルダーがあります。

<div id='menu1'></div>
<div id='menu2'></div>
<div id='menu3'></div>
<div id='menu4'></div>
<div id='menu5'></div>

私のAngularモジュールの多くは、ロードされたときにメニューを追加します( run)。それぞれが特定のスロット (つまりmenu1..5) のみを予約しているため、衝突することはありません。一部のモジュールがロードされていない場合、それらのメニューはメニュー バーに表示されません。

angular モジュールは、概念的には次のようになります。

angular.module('myModule3', [])
  .service('someService', function($http) {
    // get some data to populate menu (use $http)
    this.menuItems = ['orange', 'apple', 'banana']
  })

  .run(['someService', function(someService) {
    // create a rendered menu item
    ...
    // insert it at id="menu3"
  })

簡単にするために、レンダリングされたメニュー項目は次のようになります。

  <ul>
    <li>organge</li>
    <li>apple</li>
    <li>banana</li>
  </ul>

私はAngularにかなり慣れていないので、どこから始めればよいかわかりません。私はdirectives について調べてきましたが、いくつかのカスタム マークアップ (おそらく DOM ターゲット (つまり ) を含むカスタム メニュー タグ) が必要なため、それらがここにどのように適合するかわかりませんmenu..5。また、これをコントローラーに接続する方法は次のとおりです。私にはわかりません。

更新 上記base template(DOM 内の任意のアンカー ポイントを含む) とディレクティブ (これらのアンカー ポイントに挿入される DOM 要素を生成する) に加えて、テンプレートは DOM 要素の作成を容易にします。このテンプレートは、ディレクティブの DOM 要素が挿入される位置を含む別のファイルに配置されます (ディレクティブの定義に一致する特定のマークアップに既存のタグが置換/挿入されるディレクティブの通常の場合とは対照的に:

<menu ng-model="Model3DataService" target="#menu3">
  <ul>
    <li ng-repeat="for item in items"></li>
  </ul>
</menu>

繰り返しますが、バックボーン/jquery のバックグラウンドから来ると、これは理にかなっていますが、Angular で行うのは適切ではない可能性があります。もしそうなら、どのようにすれば基本テンプレートをモジュールに関する知識から解放し、メニューを置く場所 (つまり、メニュー バーのどのスロットを割り当てるか) を仮定しないようにすることができるか教えてください。他の解決策について聞いてうれしいです...

4

1 に答える 1

5

各モジュールには、メニュー ローダーが定義されている必要があります。

angular.module('module1', []).

factory('module1.menuLoader', function() {
    return function(callback) {
        callback(['oranges', 'bananas'])
    }
});

アプリケーションには、存在する場合にのみ任意のモジュールのメニュー項目をロードできる menu ディレクティブが含まれている必要があります。

angular.module('app', ['module1']).

directive('menu', ['$injector', function($injector) {
    return {
        restrict: 'A',
        template: 
            '<ul><li ng-repeat="item in items">{{item}}</li></ul>',
        scope: {},
        link: function($scope, $element, $attrs) {
            var menuLoaderName = $attrs.menu+'.menuLoader';
            if ($injector.has(menuLoaderName)) {
                var loaderFn = $injector.get(menuLoaderName);
                loaderFn(function(menuItems) {
                    $scope.items = menuItems;
                });
            }
        }
    };
}]); 

最終的なhtml:

<div class="content">
    <div menu="module1"></div>
    <div menu="module2"></div>
    <div menu="module3"></div>
</div>

アプリケーションを実行すると、module1 メニューのみがロードされます。他のメニュー プレースホルダーは空のままです。

ライブデモ: http://plnkr.co/edit/4tZQGSkJToGCirQ1cmb6


更新:モジュール側でマークアップを生成する場合、テンプレートが定義されているモジュールの $templateCache にテンプレートを配置し、templateName をアプリケーションに渡すのが最善の方法です。

angular.module('module1', []).

factory('module1.menuLoader', ['$templateCache', function($templateCache) {
    $templateCache.put('module1Menu', '<ul><li ng-repeat="item in items">{{item}}</li></ul>');
    return function(callback) {
        callback('module1Menu', ['oranges', 'bananas'])
    }
}]);


angular.module('app', ['module1'])

.directive('menu', ['$injector', function($injector) {
    return {
        restrict: 'A',
        template: 
            '<div ng-include="menuTemplate"></div>',
        scope: {},
        link: function($scope, $element, $attrs) {
            var menuLoaderName = $attrs.menu+'.menuLoader';
            if ($injector.has(menuLoaderName)) {
                var loaderFn = $injector.get(menuLoaderName);
                loaderFn(function(menuTemplate, menuItems) {
                    $scope.menuTemplate = menuTemplate;
                    $scope.items = menuItems;
                });
            }
        }
    };
}]);
于 2013-10-12T00:45:11.550 に答える