2015-05-15 2 views
6

Я пытаюсь реализовать угловую директиву ng-repeat, и я не понимаю, почему этот код не работает правильно.Угловой ng-repeat tool

.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». P.S. Извините за мой английский. I beginner :)

+1

FYI, используя '$ transclude' от' compile' осуждается. См. Https://docs.angularjs.org/api/ng/service/$compile –

+0

Найден чужой клон 'ng-repeat' [здесь] (http://liamruufman.com/blog/2013/05/13/ define-angularjs-directives-part1-ng-repeat-and-compile /) (он использует не устаревшую форму 'transclude' fn). См. [This plunker] (http://plnkr.co/edit/S3JsEvD1Z372dTHhfzIK?p=preview), сравнивая эту реализацию (которая работает) с вашей (надеюсь, вы увидите разницу). –

+0

аргумент компоновщика в функции компиляции в вашем случае является функцией пересылки? В моем случае я возвращаюсь из функции LINK функции компиляции с аргументом transclude fn. Это не устарело или я ошибаюсь? – memfisrain

ответ

1

Я заметил, что ваш индексный указатель неверен, когда я пишу его на консоль. изменить: 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); 
         }); 
        } 
       }); 
      } 
     } 
    } 
}) 
Смежные вопросы