【问题标题】:Dynamic NG-Controller Name动态 NG-控制器名称
【发布时间】:2014-09-05 21:16:16
【问题描述】:

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

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

我如何在 Angular 中做到这一点?我认为这很容易,但我似乎可以找到一种方法。

【问题讨论】:

  • 是否有父控制器或者这是最顶层的控制器?
  • 根据条件加载模板并在模板中设置控制器的多种方法
  • 这会有一个父控制器。
  • 最好是基于配置,而不是基于模板。如果控制器名称在配置中,我不希望将 ng-controllers 添加到所有模板中。
  • 也可以在routeProvider中设置控制器

标签: javascript angularjs angularjs-directive


【解决方案1】:

您要做的是在调用其他指令之前运行另一个指令,从某个模型中获取控制器名称删除新指令并添加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';
}]);

可能有一种方法可以插入 dynamic-ctrl 的值 ($interpolate) 而不是解析它 ($parse),但由于某种原因我无法让它工作。

【讨论】:

  • 谢谢。正是我想要的。就我而言,我想传递一个 $scope 变量而不是一个字符串。所以我只需要做 dynamic-ctrl="myScopeVariable"
  • 耐德解决方案。但是,我建议优先级为 550 而不是 100000。这样,指令在 ng-controller(优先级 600)之前但在 ng-if(优先级 600)之后执行。否则,即使元素不在页面上(如果 ng-if 为 false),您的控制器也会被初始化(在调用 $compile(elem)(scope) 期间)。此外,您可以使用链接函数的“attrs”参数访问元素的属性来处理驼峰式大小写(即:attrs.dynamicCtrl)。
【解决方案2】:

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

【讨论】:

  • 添加 :if (scope.src) elem.attr('src', "'"+scope.src+"'");支持 ng-include
  • 您包含$parse 工厂,但您没有使用它。
  • 放什么地方:if (scope.src) elem.attr('src', "'"+scope.src+"'"); ?
【解决方案3】:

就我个人而言,这里的 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
          }));
        }
      });
    }
  };
}]);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-07
    • 2012-12-06
    • 1970-01-01
    相关资源
    最近更新 更多