我尝试实现 Angular ng-repeat 指令,但我不明白为什么这段代码不能正常工作。
.directive("myRepeat", function() {
return {
transclude: "element",
priority: 1000,
compile: function(tElem, tAttrs) {
var myLoop = tAttrs.myRepeat,
match = myLoop.match(/^\s*(.+)+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$/),
indexString = match[1],
collectionString = match[2],
parent = tElem.parent();
return function($scope, iElem, iAttrs, controller, $transclude) {
$scope.$watchCollection(collectionString, function(newCollection) {
var i, block, elements = [];
// check if elements have already been rendered
if (elements.length) {
// if so remove them from DOM, and destroy their scope
for (i = 0; i < elements.length; i++) {
elements[i].el.remove();
elements[i].scope.$destroy();
}
elements = [];
}
for (i = 0; i < newCollection.length; i++) {
$transclude(function(clone, scope) {
scope[indexString] = newCollection[i];
parent.append(clone);
block = {};
block.el = clone;
block.scope = scope;
elements.push(block);
});
}
});
}
}
}
})
和 HTML 片段
<ul ng-controller="MyCtrl">
<li my-repeat="city in cities">{{city.name}}</li>
</ul>
我的问题是 LI 元素呈现正常,但它们不包含城市名称。请解释为什么会这样。我理解 ng-transclude 在原始情况下是如何工作的,当我们有带有 ng-transclude 元素的模板并且在我们的指令定义中指定 transclude: true 时,我不明白它是如何与 transclude: "element"一起工作的。 附言对不起我的英语不好。我是初学者:)
最佳答案
当我将它写入控制台时,我注意到您的 indexString 不正确。更改:match = myLoop.match(/^\s*(.+)+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s* )?$/)
到 match = myLoop.split(' ')
适合我的完整代码:
var app = angular.module('app', []);
app.controller("MyCtrl", function($scope){
$scope.cities = [{
name:'a'
}, {name: 'b'},
{name: 'c'}]
})
app.directive("myRepeat", function() {
return {
transclude: "element",
priority: 1000,
compile: function(tElem, tAttrs) {
var myLoop = tAttrs.myRepeat,
match = myLoop.split(' '),
indexString = match[0],
collectionString = match[2],
parent = tElem.parent();
console.log("match: " + match);
console.log("index string: " + indexString);
console.log("coll: " + collectionString);
var elements = [];
return function($scope, iElem, iAttrs, controller, $transclude) {
$scope.$watchCollection(collectionString, function(newCollection) {
var i;
// check if elements have already been rendered
if (elements.length) {
// if so remove them from DOM, and destroy their scope
for (i = 0; i < elements.length; i++) {
elements[i].el.remove();
elements[i].scope.$destroy();
}
elements = [];
}
for (i = 0; i < newCollection.length; i++) {
$transclude(function(clone, scope) {
scope[indexString] = newCollection[i];
parent.append(clone);
block = {};
block.el = clone;
block.scope = scope;
elements.push(block);
});
}
});
}
}
}
})
关于javascript - Angular ng-repeat 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30266962/