memfisrain
memfisrain

Reputation: 63

Angular ng-repeat implement

I try implement angular ng-repeat directive and I don't understand why this code not work right.

.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);
                        });
                    }
                });
            }
        }
    }
})

and HTML fragment

<ul ng-controller="MyCtrl">
  <li my-repeat="city in cities">{{city.name}}</li>
</ul>

My problem is that LI elements rendered normal, but they are not contain city name. Please explain me why so occurs. I understand how work ng-transclude in primitive case, when we have template with element with ng-transclude and in our directive definition specify transclude: true, but I don't understand how that work with transclude: "element". P.S. Sorry for my english. I beginner :)

Upvotes: 6

Views: 1124

Answers (1)

ngunha02
ngunha02

Reputation: 1729

I notice that your indexString is not correct when I write it to console. change: match = myLoop.match(/^\s*(.+)+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$/) to match = myLoop.split(' ')

Full code that works for me:

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);
                        });
                    }
                });
            }
        }
    }
})

Upvotes: 1

Related Questions