![](/img/trans.png)
[英]AngularJs, accessing parent scope from directive inside a nested ng-repeat
[英]AngularJS : Accessing parent scope in a transcluded directive that contains nested ng-repeat
我正在研究一個基本指令,它創建一個適合Bootstrap的div網格。 您為它提供了一組項目,並可選擇指定它可以包含的列數。 它被轉換,因此您可以定義為每個項目顯示的模板。
我將集合分成行,然后嵌套的中繼器,第一個創建每一行,第二個創建每個列(然后轉換該項的內容)。 它在這個簡單的場景中運行良好。
.directive('grid', [function() {
return {
restrict: 'AE',
template: '<div class="row" ng-repeat="row in rows"><div ng-repeat="item in row" ng-class="{\'col-md-{{columnSpan}}\': true, \'active\': isSelected(item) }"><div class="thumbnail" ng-transclude=""></div></div></div>',
transclude: true,
scope: {
items: '=grid',
columns: '@',
columnSpan: '@'
},
controller: [
'$scope', function($scope) {
}
],
link: function($scope, $el, $attrs) {
$attrs.$observe('columns', function(val) {
$scope.columns = val || 4;
});
$attrs.$observe('columnSpan', function(val) {
$scope.columnSpan = val || 12 / $scope.columns;
});
$scope.$watchCollection('items', function(items) {
$scope.rows = $scope.rows || [];
$scope.rows.length = 0;
if (!items) return;
var numRows = Math.floor(items.length / $scope.columns);
numRows = items.length % $scope.columns !== 0 ? numRows + 1 : numRows;
for (var i = 0; i < numRows; i++) {
var row = items.slice(i * $scope.columns, (i + 1) * $scope.columns);
$scope.rows.push(row);
}
});
}
};
}]);
問題在於被轉換的內容,我有時需要調用一個函數或從父作用域訪問一個項目。 例如,假設我要格式化顯示名稱,或添加單擊處理程序。
<!-- addHello is defined on the controller scope. this doesn't work -->
<div grid="items" columns="3">
{{addHello(item) || 'Undefined'}} (name is {{item.name}})
</div>
因為這會創建多個被轉換的范圍,所以我必須通過鏈接$parent
來取消范圍,直到我最終找到它。
<!-- works, but ಠ_ಠ -->
<div grid="items" columns="3">
{{$parent.$parent.$parent.$parent.addHello(item) || 'Undefined'}} (name is {{item.name}})
</div>
這也有效,但它很尷尬並且違反了得墨忒耳的法則,這很重要,因為如果我在將來改變其內部工作方式,它可能會打破被抄送的內容。 如何改進這一點以避免此問題?
功能齊全的插頭 。
使用委托模式。 我們的想法是在指令中公開一個可自定義的函數,然后插入實際操作。該操作將在transcluded范圍內觸發,調用該函數屬於父范圍。
<div grid="items" columns="3" custom-action="addHello"> //addHello() belongs to the DemoCtrl's scope
{{doAction(item) || 'Undefined'}} (name is {{item.name}}) //doAction() belongs to the translcuded scope
</div>
並將指令更新為以下內容:
scope: {
...
customAction: "&"
},
link: function($scope, $el, $attrs) {
...
$scope.doAction = function(item){
return $scope.customAction(item);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.