简体   繁体   English

动态NG控制器名称

[英]Dynamic NG-Controller Name

I want to dynamically specify a controller based on a config that we load. 我想基于我们加载的配置动态指定控制器。 Something like this: 像这样的东西:

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

How do I do this in angular? 我怎么做角度的? I thought this would be very easy, but I can seem to find a way of doing this. 我认为这很容易,但我似乎找到了这样做的方法。

What you want to do is have another directive run before anything else is called, get the controller name from some model remove the new directive and add the ng-controller directive, then re-compile the element. 你要做的是在调用其他任何东西之前运行另一个指令,从某个模型中获取控制器名称,删除新指令并添加ng-controller指令,然后重新编译该元素。

That looks like this: 看起来像这样:

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

Then you could use it in your template, like so: 然后你可以在模板中使用它,如下所示:

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

with a controller like this: 用这样的控制器:

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

There's probably a way of interpolating the value ( $interpolate ) of the dynamic-ctrl instead of parsing it ( $parse ), but I couldn't get it to work for some reason. 可能有一种方法可以插入dynamic-ctrl的值( $interpolate )而不是解析它( $parse ),但是由于某些原因我无法使它工作。

I'm using it in ng-repeat, so this is improved code for loops and sub objects: 我在ng-repeat中使用它,所以这是循环和子对象的改进代码:

Template: 模板:

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

Directive: 指示:

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

Personally the 2 current solutions here didn't work for me, as the name of the controller would not be known when first compiling the element but later on during another digest cycle. 就个人而言,这里的2个当前解决方案对我来说并不起作用,因为在第一次编译元素时将会知道控制器的名称,而在稍后的另一个摘要周期中则不知道。 Therefore I ended up using: 因此我最终使用:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM