在指令中使用 ng-transclude 进行 ng-repeat [英] ng-repeat with ng-transclude inside a directive
问题描述
我想在内容更改时创建一个具有自定义行为的列表.我尝试为此创建一个指令,但我对如何将 ng-transclude 与 ng-repeat 指令结合起来有点迷茫.有人能让我走上正轨吗?
HTML:
<div ng-controller="ctrl"><mylist items="myItem in items"><span class="etc">{{myItem}}</span></mylist>
Javascript:
angular.module('myApp', []).controller('ctrl', function ($scope) {$scope.items = ['one', 'two', 'three'];}).directive('mylist', function () {返回 {限制:'E',嵌入:'元素',替换:真的,范围:真实,模板: ['','<li ng-repeat="WhatGoesHere in items";ng-transclude></li>','</ul>'].加入(''),链接:函数(范围、元素、属性){var parts = attr.items.split(' in ');var itemPart = 零件[0];var itemsPart = part[1];scope.$watch(itemsPart, function (value) {scope.items = 值;});}}});
我在这里
标准:
- 项的模板必须在视图中定义,而不是在指令中定义,并且它必须能够访问子作用域中的项属性.理想情况下,我想像在 ng-repeat 指令中那样定义它
- 指令必须有权访问列表,以便我可以设置适当的监视和更改内容.如果可能的话,我希望能够轻松访问生成的 DOM 项(我也可以使用
element[0].querySelectorAll('ul>li')
或其他东西来做到这一点,它只需要处理铬). - 如果可能,我想重用 ng-repeat 指令中的逻辑,因为它已经做了很多我想做的事情.最好我不想复制代码.我只是想增强它的行为,而不是改变它
自己解决了问题:
我可以在编译步骤(jsfiddle)中添加ng-repeat
属性,当模板被编译并将我的属性内容提供给它时.
HTML:
<div ng-controller="ctrl"><mylist element="myItem in items">{{myItem}}</mylist>
Javascript:
var myApp = angular.module('myApp', []).controller('ctrl', function ($scope) {$scope.items = ['one', 'two', 'three'];}).directive('mylist', function ($parse) {返回 {限制:'E',嵌入:'元素',替换:真的,范围:真实,模板: ['','<li ng-transclude></li>','</ul>'].加入(''),编译:函数(tElement,tAttrs,transclude){var rpt = document.createAttribute('ng-repeat');rpt.nodeValue = tAttrs.element;tElement[0].children[0].attributes.setNamedItem(rpt);返回函数(范围,元素,属性){var rhs = attr.element.split(' in ')[1];scope.items = $parse(rhs)(scope);控制台日志(范围.项目);}}}});
I want to create a list with custom behavior when it's content changes. I try to create a directive for this but I get a bit lost with how to combine the ng-transclude with the ng-repeat directive. Can somebody put me on track?
Html:
<div ng-app="myApp">
<div ng-controller="ctrl">
<mylist items="myItem in items">
<span class="etc">{{myItem}}</span>
</mylist>
</div>
</div>
Javascript:
angular.module('myApp', [])
.controller('ctrl', function ($scope) {
$scope.items = ['one', 'two', 'three'];
})
.directive('mylist', function () {
return {
restrict:'E',
transclude: 'element',
replace: true,
scope: true,
template: [
'<ul>',
'<li ng-repeat="WhatGoesHere in items" ng-transclude></li>',
'</ul>'
].join(''),
link: function (scope, element, attr) {
var parts = attr.items.split(' in ');
var itemPart = parts[0];
var itemsPart = parts[1];
scope.$watch(itemsPart, function (value) {
scope.items = value;
});
}
}
});
I've got part of this somewhat working here
EDIT:
Criteria:
- The template of the item must be defined in the view, not in the directive and it must have access to an item property in a child scope. Ideally I want to define this like it is done in the ng-repeat directive
- The directive must have access to the list so I can set proper watches and change things. If possible I would like to have easy access to the generated DOM items (I can also do it with
element[0].querySelectorAll('ul>li')
or something, It only has to work on Chrome). - If possible I would like to reuse the logic in the ng-repeat directive because it does already do a lot of what I want. Preferably I don't want to copy the code. I just want to augment its behavior, not change it
Solved the problem myself:
I am able to do it in the compile step (jsfiddle) by adding the ng-repeat
attribute when the template is compiled and feeding it the content of my attribute.
Html:
<div ng-app="myApp">
<div ng-controller="ctrl">
<mylist element="myItem in items">{{myItem}}</mylist>
</div>
</div>
Javascript:
var myApp = angular.module('myApp', [])
.controller('ctrl', function ($scope) {
$scope.items = ['one', 'two', 'three'];
})
.directive('mylist', function ($parse) {
return {
restrict:'E',
transclude: 'element',
replace: true,
scope: true,
template: [
'<ul>',
'<li ng-transclude></li>',
'</ul>'
].join(''),
compile: function (tElement, tAttrs, transclude) {
var rpt = document.createAttribute('ng-repeat');
rpt.nodeValue = tAttrs.element;
tElement[0].children[0].attributes.setNamedItem(rpt);
return function (scope, element, attr) {
var rhs = attr.element.split(' in ')[1];
scope.items = $parse(rhs)(scope);
console.log(scope.items);
}
}
}
});
这篇关于在指令中使用 ng-transclude 进行 ng-repeat的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!