javascript 带有 angularjs 的动态菜单栏
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19328908/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dynamic menu bar with angularjs
提问by orange
I'm trying to create a menu bar using Angularjs
. I've done similar things before with Backbonejs
, but I have a hard time getting my head around how to do this with angular.
我正在尝试使用Angularjs
. 我以前用 做过类似的事情Backbonejs
,但我很难弄清楚如何用 angular 来做到这一点。
In my html
file, I have the following menu placeholder.
在我的html
文件中,我有以下菜单占位符。
<div id='menu1'></div>
<div id='menu2'></div>
<div id='menu3'></div>
<div id='menu4'></div>
<div id='menu5'></div>
A number of my angular modules add a menu when they are loaded (in run
). Each of them only reserves a particular slot (i.e. menu1..5
), so they don't clash. When some modules aren't loaded, their menu would not show in the menu bar.
我的一些 angular 模块在加载时添加了一个菜单(在 中run
)。它们中的每一个只保留一个特定的插槽(即menu1..5
),因此它们不会发生冲突。当某些模块未加载时,它们的菜单不会显示在菜单栏中。
An angular module would conceptually look like:
角度模块在概念上看起来像:
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"
})
For sake of simplicity, the rendered menu item should look like:
为简单起见,呈现的菜单项应如下所示:
<ul>
<li>organge</li>
<li>apple</li>
<li>banana</li>
</ul>
I'm fairly new to angular, so I don't really know where to begin. I've been reading up on directive
s, but don't see how they fit in here, as they require some custom markup (maybe a custom menu tag containing the DOM target (i.e. menu..5
). Also, how to connect this to a controller is not clear to me.
我对 angular 还很陌生,所以我真的不知道从哪里开始。我一直在阅读directive
s,但没有看到它们如何适应这里,因为它们需要一些自定义标记(可能是包含 DOM 目标的自定义菜单标签(即menu..5
)。此外,如何将其连接到控制器是我不清楚。
UpdateIn addition to the above base template
(containing arbitrary anchor points in the DOM) and the directive (which will produce a DOM element which will be inserted at these anchor points), a template will facilitate the creation of the DOM element. This template will be located in a separate file containing the position the directive's DOM element will be inserted to (as opposed to the usual case of directives in which an already existing tag will be replaced/inserted into specific markup that matches the directive's definition:
更新除了上述base template
(包含 DOM 中的任意锚点)和指令(将生成将插入这些锚点的 DOM 元素)之外,模板将有助于创建 DOM 元素。该模板将位于一个单独的文件中,该文件包含指令的 DOM 元素将被插入到的位置(与指令的通常情况相反,在指令中已经存在的标签将被替换/插入到与指令定义匹配的特定标记中:
<menu ng-model="Model3DataService" target="#menu3">
<ul>
<li ng-repeat="for item in items"></li>
</ul>
</menu>
Again, coming from a Backbone/jquery background this makes sense, but this may not be the right thing to do in angular. If so, please let me know how I could keep the base template free of any knowledge about the modules and assumptions of where they put their menu (i.e. which slot of the menu bar they allocate). I'm happy to hear about other solutions...
同样,来自 Backbone/jquery 背景这是有道理的,但这在 angular 中可能不是正确的做法。如果是这样,请让我知道如何让基本模板不了解有关模块的任何知识以及他们放置菜单的位置(即他们分配菜单栏的哪个插槽)的假设。我很高兴听到其他解决方案......
回答by kseb
Each module should have its menu loader defined:
每个模块都应该定义它的菜单加载器:
angular.module('module1', []).
factory('module1.menuLoader', function() {
return function(callback) {
callback(['oranges', 'bananas'])
}
});
Your application should contain menu directive which can load menu items for any module only if exists.
您的应用程序应包含菜单指令,该指令仅在存在时才能为任何模块加载菜单项。
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;
});
}
}
};
}]);
Final html:
最终的html:
<div class="content">
<div menu="module1"></div>
<div menu="module2"></div>
<div menu="module3"></div>
</div>
After running the application only module1 menu will be loaded. Other menu placeholders remain empty.
运行应用程序后,只会加载 module1 菜单。其他菜单占位符保持为空。
Live demo: http://plnkr.co/edit/4tZQGSkJToGCirQ1cmb6
现场演示:http: //plnkr.co/edit/4tZQGSkJToGCirQ1cmb6
Updated:If you want to generate markup on the module side the best way is to put the template to the $templateCache in the module where it's defined and then pass the templateName to the application.
更新:如果您想在模块端生成标记,最好的方法是将模板放在定义它的模块中的 $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;
});
}
}
};
}]);