Javascript 有角重复机具

Javascript 有角重复机具,javascript,angularjs,Javascript,Angularjs,我尝试实现angular ng repeat指令,但我不明白为什么这段代码不能正常工作 .directive("myRepeat", function() { return { transclude: "element", priority: 1000, compile: function(tElem, tAttrs) { var myLoop = tAttrs.myRepeat,

我尝试实现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);
                        });
                    }
                });
            }
        }
    }
})
.directive(“myRepeat”,function()){
返回{
转移:“元素”,
优先权:1000,
编译:功能(TELM、tAttrs){
var myLoop=tAttrs.myRepeat,
match=myLoop.match(/^\s*(.+)+in\s+(.*)\s*(\s+track\s+by\s+(.+)\s*)?$/),
indexString=匹配[1],
collectionString=匹配[2],
parent=tElem.parent();
返回函数($scope、iElem、iAttrs、controller、$transclude){
$scope.$watchCollection(collectionString,函数(newCollection){
变量i,块,元素=[];
//检查元素是否已渲染
if(元素长度){
//如果是这样,请从DOM中删除它们,并销毁它们的作用域
对于(i=0;i
和HTML片段

<ul ng-controller="MyCtrl">
  <li my-repeat="city in cities">{{city.name}}</li>
</ul>
  • {{city.name}
我的问题是LI元素呈现为正常,但它们不包含城市名称。请给我解释一下为什么会这样。我理解ng transclude在基本情况下是如何工作的,当我们有带有ng transclude的元素的模板,并且在我们的指令定义中指定transclude:true时,但我不理解它如何与transclude:“元素”一起工作。
对我的英语很抱歉。I初学者:)

我注意到,当我将索引字符串写入控制台时,它是不正确的。更改:
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);
                        });
                    }
                });
            }
        }
    }
})
var-app=angular.module('app',[]);
app.controller(“MyCtrl”,函数($scope){
$scope.cities=[{
姓名:'a'
},{name:'b'},
{name:'c'}]
})
应用程序指令(“myRepeat”,函数(){
返回{
转移:“元素”,
优先权:1000,
编译:功能(TELM、tAttrs){
var myLoop=tAttrs.myRepeat,
匹配=myLoop.split(“”),
indexString=匹配[0],
collectionString=匹配[2],
parent=tElem.parent();
console.log(“匹配:+match”);
log(“索引字符串:”+indexString);
log(“coll:+collectionString”);
var元素=[];
返回函数($scope、iElem、iAttrs、controller、$transclude){
$scope.$watchCollection(collectionString,函数(newCollection){
var i;
//检查元素是否已渲染
if(元素长度){
//如果是这样,请从DOM中删除它们,并销毁它们的作用域
对于(i=0;i
FYI,不推荐使用
编译中的
$transclude
。请参阅找到其他人的
ng repeat
克隆(它使用了
transclude
fn的非弃用形式)。请参阅将该实现(有效)与您的实现进行比较(希望您能看到差异)。在您的例子中,compile函数中的链接器参数是transclude函数?在我的例子中,我使用transcludefn参数从编译函数LINK函数返回。这不是不赞成,还是我弄错了?