AngularJS,ui.router,基于用户角色加载模板和控制器 [英] AngularJS, ui.router, load template and controller based on user role

查看:224
本文介绍了AngularJS,ui.router,基于用户角色加载模板和控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发了一个使用REST API的单页应用程序。用户需要登录才能访问应用程序。当用户登录时,他们被重定向到/ dashboard。在此网址/路线上,我想根据用户的角色(例如正常用户管理员用户)加载不同的模板和控制器。



我看过 https://github.com/angular-ui / ui-router / wiki ,但没有任何选项支持我想要达到的目标。




  • 使用templateUrl和function(stateParams)我无法注入服务,帮助我确定用户角色,以便我可以加载模板,例如视图/ 用户 /dashboard.html或视图/ 管理 /dashboard.html

  • 使用templateProvider帮助我确定用户角色,但是如何加载模板?



任何解决方案还应该根据用户角色,例如UserDashboardController或AdminDashboardController。



因此,我需要的是一个单一的路由加载不同的模板和控制器基于用户角色变量



我沿着正确的线路思考,还是应该实施另一个解决方案?


解决方案

加载基于模板和控制器的on user role



虽然技术上 ui-router templateUrl函数不支持注入服务,您可以使用 templateProvider 注入包含角色变量或加载它的服务 $ templateFactory 可返回HTML内容。请考虑以下示例:

  var app = angular.module('app',['ui.router']); 

app.service('session',function($ timeout,$ q){
this.role = null;

this.loadRole = function {
// load role using axax request and return promise
};
});

app.config(function($ stateProvider,$ urlRouterProvider){
$ stateProvider.state('dashboard',{
url:'/ dashboard',
templateProvider:function(session,$ stateParams,$ templateFactory){
return session.loadRole()。then(function(role){
if(session.role =='admin'){
return $ templateFactory.fromUrl('/ admin / dashboard.html',$ stateParams);
} else {
return $ templateFactory.fromUrl('/ user / dashboard.html',$ stateParams);
}
});
}
});

$ urlRouterProvider.otherwise('/ dashboard');
}

至于 controller 您想要使用 ng-controller 在每个模板的根元素中使用特定的控制器。或者类似地,您可以使用 controllerProvider 选项注入服务已经具有角色 templateProvider 解析。看看下面的示例 controllerProvider 选项在 ui-router 状态定义:

  controllerProvider:function(session){
if(session.role =='admin'){
return'AdminCtrl';
} else {
return'UserCtrl';
}
}

当然,您可以轻松地从此代码中删除重复的定义更容易访问的微DSL,以便为特定角色和视图定义不同的规则。



以下 演示 应该可以帮助您了解代码。



这是正确的方法吗?



通常这大大取决于上下文。为了帮助提供答案,我首先建议以下问题:




  • 提交给角色的夫妇不同?



您要仅隐藏按钮 s和其他操作元素基本上使一个页面只读的普通用户和可编辑的超级用户?如果更改将很小,我可能会使用相同的视图,只隐藏特定的元素,可能伪造一个类似于 ng-if 的指令,允许启用/禁用特定功能声明性地 only-role ='operator,admin'。另一方面,如果视图会有很大的不同,那么使用不同的模板可以大大简化标记。




  • 在特定页面上有多少 根据角色而有所不同。



在表面上看起来相似的动作在不同角色的内部工作方面不同?例如,如果您为用户 admin 角色提供编辑如果它开始向导像UI和高级用户的其他复杂形式,那么有一个单独的控制器更有意义。另一方面,如果 admin 动作是 user 动作的超集,那么拥有单个控制器似乎更容易遵循。请注意,在这两种情况下,保持控制器的事情是有利的 - 他们应该只粘贴视图封装在服务/视图模型/模型/选择一个名称< 不同的地方的应用程序?


例如,只要写下 ui即可提供导航到特定 -sref =dashboard,无论当前用户 role 如果存在于各种上下文中可能是有益的。如果是这种情况,那么在单个路由/状态下定义它们似乎更可维护,那么用于构建不同 ui-sref / ng-href 基于角色。




  • 将视图和




有时我们首先为常规的用户然后为溢价,然后为最终。在团队成员之间划分用户 admin 的页面上的工作并不罕见,特别是如果可以轻松绘制清晰的边界。在这种情况下,单独的视图 controllers 可以简单地避免冲突。当然,并非所有的彩虹和独角兽 - 团队必须非常纪律,以消除重复,很可能会发生。



希望我的建议帮助你决定。


I have developed a Single Page App that uses a REST api. Users are required to login to access the application. When a user logs in they are redirected to /dashboard. On this URL / route, I would like to load a different template and controller based on the role of the user (e.g. normal user or admin user).

I have looked at https://github.com/angular-ui/ui-router/wiki under the templates section but none of the options support what I am trying to achieve.

  • By using templateUrl and function (stateParams) I am not able to inject the service that helps me to determine the user role so that I can load the template, e.g. views/user/dashboard.html or views/admin/dashboard.html
  • By using templateProvider I am to inject the service that helps me to determine the user role, but how do I then load the template?

Any solution should also load different controllers based on the user role, for example UserDashboardController or AdminDashboardController.

So essentialy what I need is a single route that loads a different template AND controller based on a user role variable that is set in a service when a user logs in.

Am I thinking along the right lines, or should I be implementing another solution?

Any help on this would be greatly appreciated.

解决方案

Loading template and controller based on user role

While technically ui-router templateUrl function does not support injecting services you can use templateProvider to inject service that holds role variable or loads it asynchronously and then use $templateFactory to return HTML content. Consider following example:

var app = angular.module('app', ['ui.router']);

app.service('session', function($timeout, $q){
    this.role = null;

    this.loadRole = function(){
        //load role using axax request and return promise
    };
});

app.config(function($stateProvider, $urlRouterProvider){
    $stateProvider.state('dashboard', {
        url: '/dashboard',
        templateProvider: function(session, $stateParams, $templateFactory){
          return session.loadRole().then(function(role){
              if(session.role == 'admin'){
                return $templateFactory.fromUrl('/admin/dashboard.html', $stateParams);
              } else {
                return $templateFactory.fromUrl('/user/dashboard.html', $stateParams);
              }
          });
        }
      });

    $urlRouterProvider.otherwise('/dashboard');
});

As for controller you can either state that you would like to use specific controller inside root element of each template with ng-controller. Or similarly you can use controllerProvider option to inject service that will already have role resolved by templateProvider. Take a look at following example of controllerProvider option inside ui-router state definition:

controllerProvider: function(session){
  if(session.role == 'admin'){
    return 'AdminCtrl';
  } else {
    return 'UserCtrl';  
  }
}

Of course you can remove duplicates from this code easily and define a more accessible micro DSL to make defining different rules for particular roles and views easier.

The following demo should help you understand the code.

Is this a right approach?

As usually this greatly depends on context. To help you come up with an answer let me suggest following questions first:

  • How much views presented to roles differ?

Are you going to hide only couple of buttons and other action elements basically making a page read only for regular users and editable for superusers? If the changes will be small I would probably go with using the same views and only hiding particular elements, probably forging a directive similar to ng-if that would allow enabling/disabling particular functionality declaratively only-role='operator, admin'. On the other hand if views are going to be vastly different then employing different templates can simplify markup greatly.

  • How much actions available on particular page differ depending on role?

Do actions that look similar on surface differ in inner workings for different roles? In example if you have Edit action available both for user and admin role but in one case it starts wizard like UI and in other a complex form for advanced users then having a separate controller makes more sense. On the other hand if admin actions are a superset of user actions then having single controller seems easier to follow. Note that in both cases keeping controller things pays off - they should only glue views to behaviour that is encapsulated in services/view models/models/pick a name

  • Will you have many contextually separate links leading to particular page from different places of the app?

For instance being able to provide navigation to particular page by simply writing ui-sref="dashboard" regardless of the current user role may be beneficial if it exists in various contexts. If that's the case then having them defined under single route/state seems more maintainable then a conditional logic used to build different ui-sref/ng-href based on role. However you could also define routes/states dynamically based on user role - loaded dynamically or not

  • Will views and actions available to different roles on particular page evolve separately or together?

Sometimes we first build features for regular users then for premium and then for ultimate. It's not unusual to divide work on pages for user and admin between team members especially if clear boundaries can be drawn easily. In such case having separate views and controllers can simply developers work avoiding conflicts. Of course it's not all rainbows and unicorns - team must be very disciplined to remove duplication that most likely will happen.

Hope that my suggestions will help you decide.

这篇关于AngularJS,ui.router,基于用户角色加载模板和控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆