【问题标题】:Bind controllers dynamicaly via ng-controller通过 ng-controller 动态绑定控制器
【发布时间】:2015-07-15 20:34:13
【问题描述】:

我希望将 bootstrap.ui 选项卡集与一组选项卡设置一起使用。这些选项卡设置包括用于处理其内容的控制器的名称。这样我的“选项卡控件”模板就可以保持简洁。

<div tabset>
    <div ng-repeat="tab in tabs"
         tab
         active="tab.isActive">
        <span tab-heading>{{ tab.title }}</span>
        <span ng-inlcude="tab.templateUrl" ng-controller="tab.controller"></span>
    </div>
</div>

(注意:我还没有在我的代码中使用 ng-include 属性,首先测试的是 ng-controller。)

首先我尝试使用控制器名称...但 ng-controller 不喜欢这样并拒绝按预期运行。

然后我尝试通过下一个 sn-p 将名称转换为控制器。

for (var tabIdx = 0; tabIdx < tabs.length; tabIdx++) {
    var tab = tabs[tabIdx];

    if (typeof tab.controllerName == 'string') {
        var childScope = tab.scope = tab.scope || $scope.$new();

        childScope.someValue = 'I am created as [' + tab.controllerName + '] requested.';

        tab.controller = $controller(tab.controllerName, { $scope: childScope });
    }
}

但是 Angular 好心地告诉我,function 是预期的,但它得到了一个 controller(你会认为 ng-controller 不会介意得到一个控制器)。

所以我将$controller 调用更改为:

tab.controller = $controller(tab.contollerName, { $scope: childScope }).constructor;

虽然这确实有效,但有点……我的范围不是我想要的范围。

在此之后,我想为 ng-contoller 提供另一个功能:

tab.controller = $controller.bind(null, tab.contollerName, { $scope: childScope });

但是 ng-controller 找不到 $injectables。

有没有办法让它工作?

【问题讨论】:

  • ng-include 的拼写错误是真的吗?
  • 这就是我们在荷兰所说的“肥手指”。只是在浏览器中输入此代码的一个错字。

标签: javascript angularjs angular-ui-bootstrap


【解决方案1】:

我会为此创建一个指令,以动态分配控制器。

app.directive('tabCtrl', function ($controller) {
  return {
    restrict: 'A',
    controller: function ($scope, $element, $attrs) {
      return $controller($scope.tab.controller, {
        $scope:   $scope,
        $element: $element,
        $attrs:   $attrs
      });
    }
  };
}); 

<span ng-inlcude="tab.templateUrl" tab-controller="tab.controller"></span>

jsbin


如果你愿意,你可以更进一步,按照以下方式做一些事情:

app.directive('tab', function ($controller) {
  return {
    restrict: 'E',
    template: '<ng-include src="tab.template"></ng-include>',
    controller: function ($scope, $element, $attrs) {
      return $controller($scope.tab.controller, {
        $scope:   $scope,
        $element: $element,
        $attrs:   $attrs
      });
    }
  };
}); 

jsBin for the extended version

【讨论】:

  • 在深入了解 angulars $controller 之后,我发现了第三个参数“later”,一个布尔值,表示返回值不应是控制器对象,而是一个在调用时将创建控制器的函数。使用它将使“ng-controller”版本工作。但是提供的{ #scope: $scope.$new() }没有进入我的控制器......
  • 你为什么要给控制器一个$new $scope? ng-include 提供的 $scope 还不够吗?
【解决方案2】:

您可以简单地指定要在模板中使用的控制器:

控制器:

app.controller('rootCtrl', function($scope) {
  $scope.tabs = [
    { id: 1, name: 'tab1', template: 'template1.html' },
    { id: 2, name: 'tab2', template: 'template2.html' }
  ]
});

HTML:

<div ng-repeat="tab in tabs track by tab.id">
    <label class="tab">{{tab.name}}</label>
    <div ng-include="tab.template"></div>
 </div>

在模板中:

<div ng-controller="ctrl1">
  ...
</div>

在此处查看示例 plunker:http://plnkr.co/edit/vkmBhP8cr8DpiHwbs2Rd?p=preview

【讨论】:

  • 这确实有效,但这样控制器是硬编码的,而不是我的数据的一部分。但可能是可行的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-07
  • 2014-09-05
  • 2017-02-02
  • 2015-03-03
  • 2014-02-17
  • 2013-06-10
  • 1970-01-01
相关资源
最近更新 更多