ui-router动态控制器名称

时间:2018-04-09 17:58:28

标签: angularjs angular-ui-router

我有这个状态配置。

          .state(entityId + ".viewOne.estimate", {
        url: "/:stage/:firstTab",
        templateProvider: function ($templateCache, $templateFactory, $stateParams) {

          var templUrl = 'app/modules/' + entityId + '/views/tabs/viewOne/viewOne.' + $stateParams.stage + '.html';

          return $templateCache.get('./' + templUrl) || $templateFactory.fromUrl(templUrl);
        },
        controller: "estimatesCtrl",
        ncyBreadcrumb: { skip: true },
        authenticate: true,
        previousState: entityId,
        showSearchBar: true, // show the search bar in header.subBox.showR.true.html
        resolve: {
          entityModule: function () {
            return {
              value: entityId,
              displayEntity: 'Quote'
            };
          }
        }

      })

我还有一个父控制器getOneCtrl,它以父状态getOneCtrl .state加载记录数据(entityId +“。viewOne

\ testinatesCtrl是一个子控制器,其父级是getOneCtrl。

当加载getOneCtrl时,数据中有一个名为'versionId'

的字段

我想要做的是,在.state(entityId +“。viewOne.estimate加载像这样的控制器

controller: "estinatesCtrl" + versionId

这是背景故事。随着我们的应用程序扩展并在EstimatesCtrl中引入了新功能,数据库中的旧记录可能会出现新代码的问题。

返回并“修复”旧记录不是一种选择。

我们想要实现的是在每个记录中都有一个带有versionId的字段,即:1.0,1.2。等等,并创建EstimatesCtrl的等效版本,即EstimatesCtrl_1_0,EstimatesCtrl_1_1等。

当getOneCtrl加载.state中的记录详细信息(entityId +“。viewOne。,。state(entityId +”。viewOne.estimate“...获取versionId(来自getOneCtrl)并加载等效版本的”EstimatesCtrl“ “+ versionId。

这样,每条记录都可以拥有自己的EstimatesCtrl版本

这有意义吗?

知道是否以及如何做到这一点。

谢谢

2 个答案:

答案 0 :(得分:0)

controllerProvider是适用于您的情况的最佳选择,它将如下所示。

controllerProvider: function($stateParams) {
    var ctrlName = 'estinatesCtrl' + $stateParams.versionId;
    return ctrlName;
}

或者替代方法可以是使用controller作为函数选项,可以在状态定义对象中提供。为了实现相同的目的,您必须使用$controller API来提供以动态方式创建控制器的选项(通常用于单元测试用例以手动创建控制器实例)。

controller: ['$state', '$controller', '$scope', 
    function($state, $controller, $scope) {
       //perhaps you could read versionId from $state/$stateParams as well.
       $controller('estinatesCtrl' + versionId, { $scope: $scope });
    }
]

答案 1 :(得分:0)

您无法真正使用动态控制器名称,但可以动态实现控制器功能。

在下面的代码中,我定义了一个dynamicController,它将使用$injector按名称查找构建器函数,并使用它来构建控制器实例。

请注意每个"版本"控制器逻辑实际上是注册为常量的可注入函数。

另请注意,$scope等每个实例的可注入事项都应该通过locals参数传递。

app.controller("dynamicController", function($injector, $scope) {
  var version = 'v1';
  var builder = $injector.get(version + 'ControllerBuilder');
  if (builder) $injector.invoke(builder, this, {$scope:$scope});
});

app.constant("v1ControllerBuilder", function(myService) {
  console.log('Version 1');
  var ctrl = this;
  ctrl.myService = myService;
  ctrl.myVersion = 1;  
});

app.constant("v2ControllerBuilder", function() {
  console.log('Version 2');
  var ctrl = this;
  ctrl.myVersion = 2;  
});