动态NG控制器名称

时间:2014-07-15 15:28:47

标签: javascript angularjs angularjs-directive

我想基于我们加载的配置动态指定控制器。像这样:

<div ng-controller="{{config.controllerNameString}}>
    ...
</div>

我如何以角度进行此操作?我认为这很容易,但我似乎找到了这样做的方法。

3 个答案:

答案 0 :(得分:33)

你想要做的是在调用其他任何东西之前运行另一个指令,从某个模型中获取控制器名称,删除新指令并添加ng-controller指令,然后重新编译该元素。

看起来像这样:

global.directive('dynamicCtrl', ['$compile', '$parse',function($compile, $parse) {
  return {
    restrict: 'A',
    terminal: true,
    priority: 100000,
    link: function(scope, elem) {
      var name = $parse(elem.attr('dynamic-ctrl'))(scope);
      elem.removeAttr('dynamic-ctrl');
      elem.attr('ng-controller', name);
      $compile(elem)(scope);
    }
  };
}]);

然后您可以在模板中使用它,如下所示:

<div dynamic-ctrl="'blankCtrl'">{{tyler}}</div>

使用这样的控制器:

global.controller('blankCtrl',['$scope',function(tyler){
    tyler.tyler = 'tyler';
    tyler.tyler = 'chameleon';
}]);

可能有一种内插$interpolate的值(dynamic-ctrl)而非解析它($parse)的方法,但我无法得到它因某种原因工作。

答案 1 :(得分:5)

我在ng-repeat中使用它,所以这是循环和子对象的改进代码:

模板:

<div class="col-xs6 col-sm-5 col-md-4 col-lg-3" ng-repeat="box in boxes">
<div ng-include src="'/assets/js/view/box_campaign.html'" ng-dynamic-controller="box.type"></div>
</div>

指令:

mainApp.directive('ngDynamicController', ['$compile', '$parse',function($compile, $parse) {
  return {
      scope: {
          name: '=ngDynamicController'
      },
      restrict: 'A',
      terminal: true,
      priority: 100000,
      link: function(scope, elem, attrs) {
          elem.attr('ng-controller', scope.name);
          elem.removeAttr('ng-dynamic-controller');

          $compile(elem)(scope);
      }
  };
}]);

答案 2 :(得分:2)

就个人而言,这里的2个当前解决方案对我来说并不起作用,因为在第一次编译元素时将会知道控制器的名称,而在稍后的另一个摘要周期中则不知道。因此我最终使用了:

myapp.directive('dynamicController', ['$controller', function($controller) {
  return {
    restrict: 'A',
    scope: true,
    link: function(scope, elem, attrs) {
      attrs.$observe('dynamicController', function(name) {
        if (name) {
          elem.data('$Controller', $controller(name, {
            $scope: scope,
            $element: elem,
            $attrs: attrs
          }));
        }
      });
    }
  };
}]);