twitter-bootstrap 使用 AngularJS 的动态菜单项
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14297116/
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 items using AngularJS
提问by andyczerwonka
Let's say I have the following menu structure:
假设我有以下菜单结构:
<li class="dropdown"><img role="button" class="dropdown-toggle" data-toggle="dropdown" ng-src="{{avatarUrl}}" />
<ul class="dropdown-menu pull-right" role="menu">
<li ng-hide="user"><a ng-click="openLoginDialog()">Login</a></li>
<li ng-show="user"><a ng-click="logout()">Logout</a></li>
</ul>
</li>
I get the correct menu, but because I'm using ng-show/ng-hide, when I change user = false;programmatically in the controller, the login menu appears. I get why this is happening, but I'm not sure what approach to take when using Angular to prevent it. I tried an ng-repeat:
我得到了正确的菜单,但是因为我使用的是 ng-show/ng-hide,所以当我user = false;在控制器中以编程方式更改时,会出现登录菜单。我明白为什么会发生这种情况,但我不确定在使用 Angular 来防止它时采取什么方法。我尝试了 ng-repeat:
<li class="dropdown"><img role="button" class="dropdown-toggle" data-toggle="dropdown" ng-src="{{avatarUrl}}" />
<ul class="dropdown-menu pull-right" role="menu">
<li ng-repeat="action in actions"><a ng-click="{{action.command}}">{{action.name}}</li>
</ul>
</li>
with:
和:
$scope.actions = [ {
name : "Login",
command : "openLoginDialog()"
}, {
name : "Logout",
command : "logout()"
} ];
But with that strategy, nothing happens with I click the menu item. I'm not sure what the appropriate Angular approach is to what I'm sure is a pedestrian use case.
但是使用该策略,我单击菜单项时没有任何反应。我不确定适合行人用例的 Angular 方法是什么。
回答by Mark Rajcok
Use ng-switchinstead of ng-show/hide. ng-switch adds/removes elements from the DOM.
使用ng-switch而不是 ng-show/hide。ng-switch 从 DOM 中添加/删除元素。
<ul class="dropdown-menu pull-right" role="menu">
<li ng-switch="user">
<a ng-switch-when="true" ng-click="logout()">Logout</a>
<a ng-switch-default ng-click="openLoginDialog()">Login</a>
</li>
</ul>
Updateto handle @andyczerwonka's comment. Move the ng-switch up one or two levels. If spans inside uldon't bother you:
更新以处理@andyczerwonka 的评论。将 ng-switch 向上移动一层或两层。如果spanS的内部ul不打扰你:
<ul class="dropdown-menu pull-right" role="menu" ng-switch="user">
<span ng-switch-when="true">
<li><a ng-click="logout()">Logout</a></li>
<li><a ng-click="preferences()">Preferences</a></li>
</span>
<span ng-switch-default>
<li><a ng-click="openLoginDialog()">Login</a></li>
</span>
</ul>
Otherwise, how about one spanoutside the ul:
否则,span外面的一个怎么样ul:
<span ng-switch="user">
<ul class="dropdown-menu pull-right" role="menu" ng-switch-when="true">
<li><a ng-click="logout()">Logout</a></li>
<li><a ng-click="preferences()">Preferences</a></li>
</ul>
<ul class="dropdown-menu pull-right" role="menu" ng-switch-default>
<li><a ng-click="openLoginDialog()">Login</a></li>
</ul>
</span>
Fiddleshowing both methods.
小提琴显示这两种方法。
回答by Bastian Voigt
In my project I use the following setup:
在我的项目中,我使用以下设置:
angular.module('mymodule')
.controller('MenuCtrl', function ($scope, $translate, UserService) {
Define actions with roles that are allowed to use these actions:
定义具有允许使用这些操作的角色的操作:
$scope.actions = [ {
name : "menu.login",
href : "#/login",
roles : []
}, {
name : "menu.logout",
href : "#/logout",
roles : [ 'READ_ONLY', 'ADMIN' ]
}, {
name : "menu.foo",
href : "#/foo",
roles : [ 'READ_ONLY', 'ADMIN' ]
}, {
name : "menu.adminArea",
href : "#/adminArea",
roles : [ 'ADMIN' ]
} ];
Define an isAllowed function that determines if an action can be used by the current user:
定义一个 isAllowed 函数,用于确定当前用户是否可以使用某个操作:
$scope.isAllowed = function(action) {
if (action.roles && action.roles.length) {
for ( var i = 0; i < action.roles.length; ++i) {
if (jQuery.inArray(action.roles[i], UserService.roles) >= 0) {
return true;
}
}
return false;
} else {
return !(UserService.roles && UserService.roles.length);
}
};
Then use $roueChangeSuccess event to determine which actions should be displayed for the current user:
然后使用 $roueChangeSuccess 事件来确定应该为当前用户显示哪些操作:
$scope.initView = function() {
for(var i=0; i<$scope.actions.length; ++i) {
var action = $scope.actions[i];
if($scope.isAllowed(action)) {
action.isRendered = true;
} else {
action.isRendered = false;
}
}
};
$scope.$on('$routeChangeSuccess', function() {
$scope.initView();
});
});
Finally, this is my menu template:
最后,这是我的菜单模板:
<nav ng-controller="MenuCtrl">
<ul>
<span ng-repeat="action in actions" ng-switch on="action.isRendered">
<li ng-switch-when="true"><a href="{{action.href}}">{{action.name | translate}
</a></li>
</span>
</ul>
</nav>
回答by asgoth
Why don't you assign functions to your commands:
为什么不为命令分配功能:
var openLoginDialog = function() { ... };
var logout = function() { ... };
$scope.actions = [ {
name : "Login",
command : openLoginDialog
}, {
name : "Logout",
command : logout
} ];

