Я работаю над базовой директивой, которая создает сетку div, подходящую для Bootstrap. Вы даете ему набор элементов и дополнительно указываете количество столбцов, которые он может содержать. Он включен, поэтому вы можете определить шаблон, отображаемый для каждого элемента.
Я разбиваю коллекцию на строки, а затем создаю вложенные повторители, где первый создает каждую строку, а второй создает каждый столбец (а затем включает содержимое для этого элемента). Это хорошо работает в этом простом сценарии.
.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>
Это также работает, но это неудобно и нарушает закон Деметры, что важно, потому что, если я изменю то, как это работает внутри в будущем, это потенциально нарушит включенный контент. Как я могу улучшить это, чтобы избежать этой проблемы?