Angularjs 对具有使用XHR检索的数据的指令的模板使用ng include
我使用ng include是为了包含一个持久菜单,它存在于我的SPA的所有视图中 问题是,我希望根据每个用户类型(管理员、来宾、用户等)在此菜单中显示不同的选项和内容,这需要首先解决服务函数authService.loadCurrentUser 为了方便地管理这些内容,我创建了一个简单的指令,它在编译阶段接受具有所需访问级别的属性 如果给定用户的权限不足,则删除元素及其子元素 因此,在尝试让ng include通过routeProvider函数失败后,我尝试使用ng init,但似乎没有任何效果,在我注销时,用户角色仍然未定义 我正在考虑尝试一种新的方法,使整个菜单成为一个指令,其中包括适合每种用户类型的模板,但首先我想尝试解决这个问题 指令:Angularjs 对具有使用XHR检索的数据的指令的模板使用ng include,angularjs,angularjs-directive,angularjs-ng-include,Angularjs,Angularjs Directive,Angularjs Ng Include,我使用ng include是为了包含一个持久菜单,它存在于我的SPA的所有视图中 问题是,我希望根据每个用户类型(管理员、来宾、用户等)在此菜单中显示不同的选项和内容,这需要首先解决服务函数authService.loadCurrentUser 为了方便地管理这些内容,我创建了一个简单的指令,它在编译阶段接受具有所需访问级别的属性 如果给定用户的权限不足,则删除元素及其子元素 因此,在尝试让ng include通过routeProvider函数失败后,我尝试使用ng init,但似乎没有任何效果
'use strict';
/* Directives */
angular.module('myApp.directives', []).
directive('restrict', function(authService){
return{
restrict: 'A',
prioriry: 100000,
scope: {
// : '@'
},
link: function(){
// alert('ergo sum!');
},
compile: function(element, attr, linker){
var user = authService.getUser();
if(user.role != attr.access){
console.log(attr.access);
console.log(user.role);//Always returns undefined!
element.children().remove();
element.remove();
}
}
}
});
服务:
'use strict';
/* Services */
angular.module('myApp.services', []).
factory('authService', function ($http, $q) {
var authServ = {};
var that = this;
that.currentUser = {};
authServ.authUser = function () {
return $http.head('/users/me', {
withCredentials: true
});
},
authServ.getUser = function () {
return that.currentUser;
},
authServ.setCompany = function (companyId) {
that.currentUser.company = companyId;
},
authServ.loadCurrentUser = function () {
var defer = $q.defer();
$http.get('/users/me', {
withCredentials: true
}).
success(function (data, status, headers, config) {
console.log(data);
that.currentUser.company = {};
that.currentUser.company.id = that.currentUser.company.id ? that.currentUser.company.id : data.main_company;
that.currentUser.companies = [];
for (var i in data.roles) {
that.currentUser.companies[data.roles[i]['company']] = data.roles[i]['company_name'];
if (data.roles[i]['company'] == that.currentUser.company.id){
that.currentUser.role = data.roles[i]['role_type'];
that.currentUser.company.name = data.roles[i]['company_name'];
// console.log(that.currentUser.role);
}
}
// defer.resolve(data);
defer.resolve();
}).
error(function (data, status, headers, config) {
that.currentUser.role = 'guest';
that.currentUser.company = 1;
defer.reject("reject");
});
return defer.promise;
}
return authServ;
});
菜单控制器:
angular.module('myApp.controllers', []).
controller('menuCtrl', function($scope, $route, $location, authService){
//TODO: Check if this assignment should be local to each $scope func in order to be compliant with 2-way data binding
$scope.user = authService.getUser();
console.log($scope.user);
// $scope.companies = $scope.user.companies;
$scope.companyOpts = function(){
// var user = authService.getUser();
if(typeof $scope.user.company == 'undefined')
return;
var companies = [];
companies[$scope.user.company.id] = $scope.user.company.name;
for(var i in $scope.user.companies){
if(i != $scope.user.company.id){
companies[i] = $scope.user.companies[i];
}
}
// console.log(companies);
// if(nonCurrentComapnies.length > 0){
console.log(companies);
return companies;
// }
}
$scope.$watch('user.company.name', function(company){
for(var i in $scope.user.companies)
if(company == $scope.user.companies[i].id)
authService.setCompany(i);
});
$scope.$watch(function(){return authService.getUser().company; }, function(company){
//Refresh the page on company change here, first time, and each time the user changes the select
// $scope.companyOpts();
// $scope.currentComapany = company;
})
;})
主SPA HTML页面:
<div ng-init="authservice.loadCurrentUser" ng-include src="'partials/menu.html'"></div>
应仅对管理员可见的菜单元素:
<ul class="left" restrict access="admin">
<li>You are the admin!</li>
</ul>
- 你是管理员李>
提前感谢您的帮助 我个人会用“反向”的方式。这意味着:当用户角色是“管理员”或“用户”等时,我将添加菜单
这样,您可以在“restrict”指令中执行以下操作:
...
var roleListener = $scope.$watch('user.role', function (newVal, oldVal) {
if (newVal == $scope.access) {
// add the menu items
// supposed that loadcurrentuser be called only once
// we should clear the watch
roleListener();
} else {
// personally, I would remove the item here too
// so the menu would be added or removed when user.role update
}
});
...
还有一件事,对于仅基于用户角色的显示菜单,您可以使用如下内容:
<ul class="left" ng-switch="user.role">
<li ng-switch-when="admin">You are the admin!</li>
<li ng-switch-when="user">You are the user!</li>
<li ng-switch-default><img src="some-thing-running.gif"/>Your menu is loading, please wait...</li>
</ul>
- 您是管理员李>
- 您就是用户李>
- 您的菜单正在加载,请稍候
让神奇的AngularJS绑定为您呈现菜单 对authServ.getUser的调用还应通过内部调用返回一个承诺
authServ.loadCurrentUser
应该对其进行一些修改,以检查用户上下文是否存在,以避免进行另一个API调用并始终使用用户上下文返回resolve:
defer.resolve(that.currentUser);
加载用户上下文也应该尽早完成,因为这样可以启用应用程序的授权。app.run函数可用于此目的
希望它对其他人有帮助。发布您的控制器代码。发布后,我不确定它是否相关。虽然相关,但确实相关,您使用的是
ng init=“authservice.loadCurrentUser”
,因此authservice
必须附加到$scope
,如果您没有,则不会调用authservice.loadCurrentUser
。另外,您应该使用ng init=“authservice.loadCurrentUser()”
来实际调用该函数。我尝试了两种方法,并最终确定在HTML语法中从函数中去掉大括号是一种角度约定。无论如何,如何将作用域附加到authService?您在哪里看到了在HTML语法中,从函数中去掉大括号是一种角度约定
?我很想知道ngInit
采用表达式,authservice.loadCurrentUser
将被计算为函数,authservice.loadCurrentUser()
将被计算为函数调用。对于范围,您只需要$sopce.authService=authService
。