[英]Dynamic menu bar with angularjs
我正在尝试使用Angularjs
创建菜单栏。 我之前在Backbonejs
也做过类似的事情,但是我很难理解如何使用angular做到这一点。
在我的html
文件中,我具有以下菜单占位符。
<div id='menu1'></div>
<div id='menu2'></div>
<div id='menu3'></div>
<div id='menu4'></div>
<div id='menu5'></div>
我的许多角度模块在加载( run
)时都会添加一个菜单。 它们每个都只保留一个特定的插槽(即menu1..5
),因此它们不会发生冲突。 未加载某些模块时,其菜单将不会显示在菜单栏中。
角度模块在概念上看起来像:
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非常陌生,所以我真的不知道从哪里开始。 我一直在阅读directive
s,但看不到它们的位置,因为它们需要一些自定义标记(可能是包含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>
同样,从Backbone / jquery的背景来看这是有道理的,但这在角度上可能不是正确的选择。 如果是这样,请让我知道如何使基本模板不受有关模块和菜单放置位置的假设(即,它们分配菜单栏的哪个插槽)的知识。 我很高兴听到其他解决方案...
每个模块都应定义其菜单加载器:
angular.module('module1', []).
factory('module1.menuLoader', function() {
return function(callback) {
callback(['oranges', 'bananas'])
}
});
您的应用程序应包含菜单指令,该指令只能在存在的任何模块中加载菜单项。
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;
});
}
}
};
}]);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.