我有一个小部件,我想在一个页面上反复使用。它有自己的控制器。问题是它需要一个数据来操作(基本上是一个键),每个键都包含在父控制器中。
这是一个例子(显然是错误的)
http://plnkr.co/edit/VajgOr1LqpLDnbEJcvor?p=preview
脚本:
angular.module('myApp', [])
.controller('ParentCtrl', ['$scope',
function($scope) {
$scope.keyForChartABC = "somekey1";
$scope.keyForChartXYZ = "somekey2";
$scope.keyForChartLALA = "somekey3";
}
])
.controller('ChartCtrl', ['$scope',
function($scope) {
//todo: have $scope.key assigned from parent somehow
//not shown: use $scope.key to pull data and format chart data
}
])
指数:
<!-- ng-init like this is quite wrong -->
<div ng-init="key = keyForChartABC"
ng-include="'chartwidget.html'"></div>
<hr>
<div ng-init="key = keyForChartXYZ"
ng-include="'chartwidget.html'"></div>
<hr>
<div ng-init="key = keyForChartLALA"
ng-include="'chartwidget.html'"></div>
chartwidget:
<div ng-controller="ChartCtrl">
<p>Drawing chart for data: {{key}}</p>
<p>some chart directive here</p>
</div>
正如你在plunker中看到的那样,我在这里尝试使用ng-init并不起作用 - 所有子控制器的键最终都具有相同的值。
我已经使用ng-repeat和父数据中的一组数据,不知何故$ index将每个子项设置为正确的索引并保留一个值。但是我想在这种情况下避免使用ng-repeat,这样我就可以更好地控制布局。
答案 0 :(得分:7)
创建可重复使用的小部件正是指令的目的。您可以创建一个非常容易处理窗口小部件输出的指令。
我分叉你的plunker并对其进行修改以将其更改为使用指令。
以下是一些亮点:
首先,您的模板不再需要在其中定义的控制器。
<div>
<p>Drawing chart for data: {{key}}</p>
<p>some chart directive here</p>
</div>
接下来,定义了一个指令,其中包含一个隔离范围,该范围对于指令的每个实例都是唯一的:
.directive('chartWidget', function(){
return {
restrict: 'E',
scope: {
key: '='
},
templateUrl : 'chartwidget.html'
}
})
最后,该指令在HTML中声明。请注意JavaScript中指令的camel-case名称,但HTML中的带连字符的名称:
<div>
<chart-widget key="keyForChartABC"></chart-widget>
<hr>
<chart-widget key="keyForChartXYZ"></chart-widget>
<hr>
<chart-widget key="keyForChartLALA"></chart-widget>
</div>
修改强>
我更新了plunker以显示将指令属性绑定到内部控制器。此方法使用ControllerAs语法定义控制器,并将指令的作用域绑定到控制器作用域。
相关变化:
.directive('chartWidget', function(){
return {
restrict: 'E',
scope: {
key: '='
},
templateUrl : 'chartwidget.html',
controller: 'chartWidgetController',
controllerAs: 'ctrl',
bindToController: true
}
})
.controller('chartWidgetController', function(){
console.log(this.key);
})
对模板进行一些小改动以支持ControllerAs:
<div>
<p>Drawing chart for data: {{ctrl.key}}</p>
<p>some chart directive here</p>
</div>
请注意,尝试在模板中使用ng-controller=
将导致模板与为指令创建的范围对象具有不同的范围对象,并且控制器将无法访问指令中定义的属性。
另请注意,bindToController
是角度1.3.x或更高的功能。在角度1.2.x或更早版本中,您唯一的选择是使用$scope.$watch
来监控隔离范围以进行更改。