在自定义指令中,如何在生成模板之前执行逻辑?
In a custom directive, how can I perform logic before generating the template?
我想编写一个自定义指令,它接受一个字符串数组,并将其呈现为 table,如下所示:
'string1' | 'string2' | 'string3' | 'string4'
'string5' | 'string6' | 'string7' | 'string8'
'string9' | 'string10' | 'string11' | 'string12'
应该这样使用:
<div class="my-directive" values="values" rowsize="4"></div>
我认为实现此目标的适当策略是首先将 values
拆分为大小为 rowsize
的数组。然后,使用内部 ng-repeat
渲染 ng-repeat
。所以指令的输出 DOM 看起来像这样:
<table>
<tr ng-repeat="part in parts">
<td ng-repeat="value in part">
{{value}}
</td>
</tr>
</table>
这意味着在指令中我需要首先做一些逻辑(将数组拆分成更小的数组),然后使用ng-repeat
如上所示。
该指令也可以使用手动 DOM 操作来编写,但我想以 'the Angular' 的方式做事 :)
所以,问题是:在自定义指令中,如何先做一些逻辑(通常在link
函数中完成),然后生成一个模板(通常放在template
属性)?
这应该可以解决问题:http://plnkr.co/edit/UYMQtMuZeJRcSQynHUGW?p=info
基本上,我们需要动态创建包含项目数组的行对象。如果我们没有达到允许的最大列数,我们只想添加到这个项目数组,正如通过 maxColumns
:
传递到指令中所指定的那样
正如您将通过 plunker 看到的那样,您可以修改 HTML 中的 max-columns
属性,指令应该适当地绘制:
app.controller('MainCtrl', function($scope) {
$scope.values = [
'string1','string2','string3','string4','string5','string6',
'string7','string8','string9','string10','string11','string12'
];
});
app.directive('myTable', function() {
var templateHtml =
'<table border="1">' +
'<tr ng-repeat="row in rows">' +
'<td ng-repeat="item in row.items">{{item}}</td>' +
'</tr>' +
'</table>';
return {
restrict: 'E',
template: templateHtml,
scope: {
values: '=',
maxColumns: '@'
},
link: function(scope, element, attrs) {
scope.rows = [];
scope.rows.push(_getNewRow())
function _getNewRow() {
return { items: [] };
}
_.each(scope.values, function(value) {
currentRow = _.last(scope.rows);
if (currentRow.items.length < scope.maxColumns) {
currentRow.items.push(value);
} else {
currentRow = _getNewRow();
currentRow.items.push(value);
scope.rows.push(currentRow);
}
});
}
}
});
我想编写一个自定义指令,它接受一个字符串数组,并将其呈现为 table,如下所示:
'string1' | 'string2' | 'string3' | 'string4'
'string5' | 'string6' | 'string7' | 'string8'
'string9' | 'string10' | 'string11' | 'string12'
应该这样使用:
<div class="my-directive" values="values" rowsize="4"></div>
我认为实现此目标的适当策略是首先将 values
拆分为大小为 rowsize
的数组。然后,使用内部 ng-repeat
渲染 ng-repeat
。所以指令的输出 DOM 看起来像这样:
<table>
<tr ng-repeat="part in parts">
<td ng-repeat="value in part">
{{value}}
</td>
</tr>
</table>
这意味着在指令中我需要首先做一些逻辑(将数组拆分成更小的数组),然后使用ng-repeat
如上所示。
该指令也可以使用手动 DOM 操作来编写,但我想以 'the Angular' 的方式做事 :)
所以,问题是:在自定义指令中,如何先做一些逻辑(通常在link
函数中完成),然后生成一个模板(通常放在template
属性)?
这应该可以解决问题:http://plnkr.co/edit/UYMQtMuZeJRcSQynHUGW?p=info
基本上,我们需要动态创建包含项目数组的行对象。如果我们没有达到允许的最大列数,我们只想添加到这个项目数组,正如通过 maxColumns
:
正如您将通过 plunker 看到的那样,您可以修改 HTML 中的 max-columns
属性,指令应该适当地绘制:
app.controller('MainCtrl', function($scope) {
$scope.values = [
'string1','string2','string3','string4','string5','string6',
'string7','string8','string9','string10','string11','string12'
];
});
app.directive('myTable', function() {
var templateHtml =
'<table border="1">' +
'<tr ng-repeat="row in rows">' +
'<td ng-repeat="item in row.items">{{item}}</td>' +
'</tr>' +
'</table>';
return {
restrict: 'E',
template: templateHtml,
scope: {
values: '=',
maxColumns: '@'
},
link: function(scope, element, attrs) {
scope.rows = [];
scope.rows.push(_getNewRow())
function _getNewRow() {
return { items: [] };
}
_.each(scope.values, function(value) {
currentRow = _.last(scope.rows);
if (currentRow.items.length < scope.maxColumns) {
currentRow.items.push(value);
} else {
currentRow = _getNewRow();
currentRow.items.push(value);
scope.rows.push(currentRow);
}
});
}
}
});