通过 ng-controller 动态绑定控制器
Bind controllers dynamicaly via ng-controller
我希望使用带有一系列选项卡设置的 bootstrap.ui 选项卡集。这些选项卡设置包括用于处理其内容的控制器的名称。这样我的 'tab-control' 模板就会保持轻便和干净。
<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 不喜欢那样并且拒绝按预期运行。
然后我尝试通过下一个片段将名称翻译成控制器。
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。
有没有办法让它工作?
您可以简单地指定要在模板中使用的控制器:
控制器:
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
我会为此创建一个指令,以动态分配控制器。
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>
如果你愿意,你可以更进一步,按照以下思路做一些事情:
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
});
}
};
});
我希望使用带有一系列选项卡设置的 bootstrap.ui 选项卡集。这些选项卡设置包括用于处理其内容的控制器的名称。这样我的 'tab-control' 模板就会保持轻便和干净。
<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 不喜欢那样并且拒绝按预期运行。
然后我尝试通过下一个片段将名称翻译成控制器。
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。
有没有办法让它工作?
您可以简单地指定要在模板中使用的控制器:
控制器:
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
我会为此创建一个指令,以动态分配控制器。
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>
如果你愿意,你可以更进一步,按照以下思路做一些事情:
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
});
}
};
});