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

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

问题描述

我开发了一个使用 REST api 的单页应用程序.用户需要登录才能访问该应用程序.当用户登录时,他们被重定向到/dashboard.在此 URL/路由上,我想根据用户的角色(例如普通 useradmin 用户)加载不同的模板和控制器.

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).

我看过https://github.com/angular-ui/ui-router/wiki 在模板部分下,但没有一个选项支持我想要实现的目标.

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.

  • 通过使用 templateUrl 和函数 (stateParams),我无法注入帮助我确定用户角色的服务,以便我可以加载模板,例如views/user/dashboard.html 或 views/admin/dashboard.html
  • 通过使用 templateProvider,我将注入帮助我确定用户角色的服务,但我如何加载模板?
  • 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?

任何解决方案还应根据用户角色加载不同的控制器,例如 UserDashboardController 或 AdminDashboardController.

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

因此,我需要的是一个单一的路由,它根据用户登录时在服务中设置的用户角色变量加载不同的模板和控制器.

我的思路是否正确,还是应该实施其他解决方案?

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

对此的任何帮助将不胜感激.

Any help on this would be greatly appreciated.

推荐答案

根据用户角色加载模板和控制器

虽然技术上ui-router templateUrl 函数不支持注入服务,但您可以使用templateProvider 注入持有role<的service/code> 变量或异步加载它,然后使用 $templateFactory 返回 HTML 内容.考虑以下示例:

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');
});

对于controller,您可以使用ng-controller 声明您希望在每个模板的根元素内使用特定的控制器.或者类似地,您可以使用 controllerProvider 选项来注入 service已经将 role 解析为 templateProvider.看看以下 ui-router 状态定义中的 controllerProvider 选项示例:

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';  
  }
}

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

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.

通常这在很大程度上取决于上下文.为了帮助想出一个答案,让我先提出以下问题:

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?

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

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?

表面上看起来相似的动作在不同角色的内部运作上是否不同?例如,如果您有 Edit 操作可用于 useradmin 角色,但在一种情况下,它启动 wizard 就像UI 和其他复杂形式的高级用户,然后拥有一个单独的 controller 更有意义.另一方面,如果 admin 动作是 user 动作的超集,那么拥有单个控制器似乎更容易遵循.请注意,在这两种情况下,保持 controller 的东西都是值得的 - 他们应该只将视图粘合到封装在服务/视图模型/模型/选择名称中的行为

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?

例如,无论当前用户的角色如何,只需编写ui-sref="dashboard"即可提供特定页面的导航如果它存在于各种环境中,则可能是有益的.如果是这种情况,那么在单个路由/状态下定义它们似乎更易于维护,然后用于基于角色构建不同的 ui-sref/ng-href 的条件逻辑.但是,您也可以根据用户角色动态定义路由/状态 - 动态加载与否

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?

有时我们首先为普通用户构建功能,然后是高级用户,然后是终极用户.在团队成员之间为 useradmin 分配页面上的工作并不罕见,特别是如果可以轻松划出清晰的边界.在这种情况下,拥有单独的 viewscontrollers 可以让开发人员轻松避免冲突.当然,并非所有彩虹和独角兽都如此 - 团队必须非常自律,以消除最有可能发生的重复.

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天全站免登陆