2015-05-15 16 views
6

Provo a implementare la direttiva angolare ng-repeat e non capisco perché questo codice non funzioni correttamente.Strumento angolare 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); 
         }); 
        } 
       }); 
      } 
     } 
    } 
}) 

e frammento di HTML

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

Il mio problema è che gli elementi LI resi normale, ma non sono contengono il nome della città. Per favore, spiegami perché succede così. Capisco come funziona ng-transclude in caso primitivo, quando abbiamo template con elemento con ng-transclude e nella nostra definizione direttiva specificare transclude: true, ma non capisco come funziona con transclude: "elemento". P.S. Mi scusi per il mio inglese. Io principiante :)

+1

FYI, usando '$ transclude' da' compile' è deprecato. Vedere https://docs.angularjs.org/api/ng/service/$compile –

+0

Trovato clone di qualcun altro di 'ng-repeat' [qui] (http://liamkaufman.com/blog/2013/05/13/ understanding-angularjs-directives-part1-ng-repeat-and-compile /) (usa la forma non deprecata di 'transclude' fn). Vedi [questo plunker] (http://plnkr.co/edit/S3JsEvD1Z372dTHhfzIK?p=preview) confrontando l'implementazione (che funziona) con la tua (si spera che tu possa vedere la differenza). L'argomento linker –

+0

nella funzione di compilazione nel tuo caso è funzione di conversione? Nel mio caso ritorno dalla funzione LINK della funzione di compilazione con l'argomento FN di conversione. Questo non è deprecato o mi sbaglio? – memfisrain

risposta

1

Ho notato che indexString non è corretto quando lo scrivo alla console. cambiare: match = myLoop.match(/^\s*(.+)+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$/)-match = myLoop.split(' ')

codice completo che funziona per 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); 
         }); 
        } 
       }); 
      } 
     } 
    } 
}) 
Problemi correlati