1

次のディレクティブがあります。私は通常、質問に答えようとしている人が重要な部分に集中できるように、あまりにも多くのコードを投稿するのは好きではありませんが、ここで何が間違っているのかわからないので、そうしなければなりません.

これは、要素のすべての子を繰り返すディレクティブです。最初のレンダリングは機能しますが、リストを変更するとめちゃくちゃになります。使用例については、このjsFiddleを参照してください。アイテムを削除して、何が問題なのかを確認してください。

bigblind = window.bigblind || angular.module("bigblind",[]);

bigblind.directive("repeatInside", function(){
    var makeChildScope = function(scope, index, key, val, keyIdentifier, valIdentifier){
        childScope = scope.$new();
        childScope.index = index
        if (keyIdentifier) childScope[keyIdentifier] = index;
        childScope[valIdentifier] = val;
        childScope.first = (index == 0);
        return childScope
    };
    var ddo = {
        transclude:true,
        compile: function(element, attrs, transclude){
            return function($scope, $element, $attr){
                var expression = $attr.repeatInside;
                var match = expression.match(/^\s*(.+)\s+in\s+(.*?)$/)
                var lhs, rhs
                var keyIdentifier, valIdentifier, hashFnLocals = {};


                if(!match){
                    throw "Expected expression in form of '_item_ in _collection_[ track by _id_]' but got " + expression;
                }

                lhs = match[1];
                rhs = match[2];

                match = lhs.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);
                if (!match) {
                    throw "bad left hand side in loop";
                }
                valIdentifier = match[3] || match[1];
                keyIdentifier = match[2];

                $scope.$watch(rhs, function(newval, oldval) {
                    var childScope, index = 0

                    for (var child in $element.children){
                        child.remove();
                    }

                    if (angular.isArray(newval)){
                        for (index=0; index<newval.length; index++) {
                            childScope = makeChildScope($scope, index, index, newval[index], keyIdentifier, valIdentifier);
                            transclude(childScope, function(clone){
                                clone.scope = childScope;
                                $element.append(clone);
                            });
                        }
                    }else{
                        for (key in newval){
                            if (newval.hasOwnProperty(key) && !key[0] == "$") {
                                childScope = makeChildScope($scope, index, key, newval[key], keyIdentifier, valIdentifier);
                                index += 1;
                                transclude(childScope, function(clone){
                                    clone.scope = childScope;
                                    $element.append(clone);
                                });
                            }
                        }
                    }
                }, true);
            }   
        }
    };
    return ddo
})
4

2 に答える 2

1

問題は で発生していchild.remove();ます。ループが実際には子を繰り返し処理していないことに気付くでしょう。for (var child in $element.children)

次の式をログに記録すると、奇妙な結果が得られます

(a) console.log($element);
(b) console.log($element[0]);
(c) console.log(angular.element($element[0]));

与える

(a) [dl, ready: function, toString: function, eq: function, push: function, sort: function…]
(b) <dl repeat-inside=​"word in dict">​…​&lt;/dl>​
(c) [dl, ready: function, toString: function, eq: function, push: function, sort: function…]

さらに、API は実際にはangular.element.children()ありませんangular.element.children。しかし$element、配列であり、DOM の子はありません。ただし、最初の要素は、<dl>探している DOM 要素を参照しています。

したがって、これを適切なJQuery 要素として期待する$element[0]か、提供することになります。しかし、これらのコンソール ログからわかるように、私たちは輪になってしまうだけです。angular.element($element[0])

誰かがこれに光を当ててくれることを願っています。

于 2013-07-16T15:46:49.043 に答える
-1

私は子供たちを手に入れ、取ることでそれらを取り除くことができましたangular.element($element[0]).children()^

于 2013-07-20T12:17:15.900 に答える