6

Il problema è che la direttiva figlio si collega al genitore, tuttavia la sintassi {{name}} viene ignorata da ng-repeat. Quale sarebbe la strada giusta per raggiungere questo obiettivo?Direttiva angolare/direttiva figlio all'interno di ng-repeat

HTML (Main direttiva/bambino)

<compact-select 
    no-item-selected-text="Add a Customer" 
    no-item-selected-icon="fa-user" 
    search-placeholder="Type a customer name" 
    cs-model="customer" 
    cs-items="contacts" 
> 
    <display-item-template> 
     <span>{{name}}</span> 
     or 
     <span>{{item.name}}</span> 
    </display-item-template> 
</compact-select> 

direttiva

angular.module('core').directive('compactSelect', [function($timeout) { 
    return { 
     templateUrl : 'modules/core/views/components/compact-select-tpl.html', 
     bindToController: true, 
     transclude: true, 
     scope: { 
      noItemSelectedText: '@', 
      noItemSelectedIcon: '@', 
      csModel: '=', 
      csItems: '=csItems' 
     }, 
     controllerAs : 'ctrl', 
     controller : function($scope) { 

     } 
    }; 
}]).directive('displayItemTemplate', function($timeout) { 
    return { 
     require: '^compactSelect', 
     restrict: 'E' 
    } 
}); 

direttiva Template (moduli/centrali/views/componenti/compact-select-tpl.html)

<div class="compact-select-repeater-box" style="" > 
    <div ng-transclude ng-repeat="item in ctrl.csItems | filter:searchParam" class="compact-select-repeater" ng-class="ctrl.getHighlightedClass(item)" ng-click="ctrl.itemSelected(item)"> 
     <span>{{item.name}}</span> 
     <span>{{item.id}}</span> 
    </div> 
    <div style="position:absolute;bottom:0"> 
     <a href="#">+ Click here to add customer {{ctrl.message}}</a> 
    </div> 
</div> 

posso vedere che

<span>{{item.name}}</span> 
<span>{{item.id}}</span> 

viene sostituito con

<span></span> 
or 
<span>{{item.name}}</span> 

e non con

<span>{{name}}</span> 
or 
<span>{{item.name}}</span> 

Domanda: Come si ottiene ng-repeat per rispettare la sintassi dei collegamenti html dalla direttiva figlio? O c'è un altro modo per raggiungere questo obiettivo?

risposta

8

Se non sbaglio, stai cercando di creare uno list view tale che l'utente possa fornire lo template elenco, ma il i metodi (clic, ecc.) sarebbero già resi disponibili attraverso la direttiva.

Ora, dal momento che angular 1.3, il transcluded scope è un figlio del directive isolated scope,

così, nel tuo caso, se si segue la gerarchia corretta, è possibile accedere al directive scope dall'interno del modello fornito dall'utente.

Ecco la gerarchia di portata:

Directive isolated scope ->ng-repeat new scope for every row ->transcluded scope.

quindi, se si desidera accedere directive scope dal transcluded scope, si avrebbe bisogno di fare $parent (per il GN-repeat) e poi accedere item.name, come di seguito:

<display-item-template>    
     <span>Item Name: {{$parent.item.name}}</span>    
</display-item-template> 

Inoltre, non è necessario bisogno le associazioni all'interno del vostro compact-select-tpl, perché si vuole che il contenuto provenga da inclusione:

<div class="compact-select-repeater-box" style="" > 

    <div ng-transclude ng-repeat="item in ctrl.csItems | filter:searchParam" 
    class="compact-select-repeater" 
    ng-class="ctrl.getHighlightedClass(item)" 
    ng-click="ctrl.itemSelected(item)"> 
     <!-- <span>{{item.name}}</span> 
     <span>{{item.id}}</span> --> 
    </div> 

    <div style="position:absolute;bottom:0"> 
     <a href="#">+ Click here to add customer {{ctrl.message}}</a> 
    </div> 
</div> 
+0

wow ... questo è fantastico funziona bene. Grazie per aver spiegato il ciclo di vita dell'ambito della direttiva. – Tim

2

La direttiva displayItemTemplate che si esegue la transizione all'interno dell'altra direttiva ha già i suoi dati interpolati {{name}} e {{item.name}}.

Se non si dispone di queste variabili in $ scope, verranno escluse stringhe vuote all'interno degli span.

Quindi, nella direttiva compactSelect, il div che viene transclusionato avrà il contenuto sovrascritto.

Se si sposta la direttiva displayItemTemplate all'interno del modello dell'altra direttiva, la ripetizione funzionerà. (È necessario rimuovere ng (transclude e transclude:. Vera

Fiddle

Inoltre, se si utilizza bindToController, non mettere gli attributi all'interno portata

function compactSelect() { 
 
    return { 
 
    template : [ 
 
     '<div class="compact-select-repeater-box" style="" >', 
 
     '<div ng-repeat="item in ctrl.csItems | filter:searchParam" class="compact-select-repeater" ng-class="ctrl.getHighlightedClass(item)" ng-click="ctrl.itemSelected(item)">', 
 
     '<display-item-template>', 
 
      '<span>{{item.name}}</span>', 
 
     '</display-item-template>', 
 
     '</div>', 
 
     '<div style="position:absolute;bottom:0">', 
 
      '<a href="#">+ Click here to add customer {{ctrl.message}}</a></div></div>', 
 
    ].join(''), 
 
    bindToController: { 
 
     noItemSelectedText: '@', 
 
     noItemSelectedIcon: '@', 
 
     csItems: '=csItems' 
 
    }, 
 
    scope: {}, 
 
    controllerAs : 'ctrl', 
 
    controller : function($scope) { 
 

 
    } 
 
    } 
 
} 
 
function displayItemTemplate() { 
 
    return { 
 
     require: '^compactSelect', 
 
     restrict: 'E' 
 
    } 
 
} 
 
function SuperController() { 
 
\t this.name = "a name"; 
 
\t this.contacts = [{name:"rob"}, {name:"jules"}, {name:"blair"}]; 
 
} 
 
angular.module('myApp', []); 
 
angular 
 
    .module('myApp') 
 
    .controller('SuperController', SuperController) 
 
    .directive('compactSelect', compactSelect) 
 
    .directive('displayItemTemplate', displayItemTemplate);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script> 
 
<div ng-app="myApp"> 
 
    <div ng-controller="SuperController as s"> 
 
    <compact-select 
 
     no-item-selected-text="Add a Customer" 
 
     no-item-selected-icon="fa-user" 
 
     search-placeholder="Type a customer name" 
 
     cs-items="s.contacts"> 
 
    </compact-select> 
 
    </div> 
 
</div>

+0

Grazie vedo dove andare a parare, ma non questo è quello che sto cercando di achive. – Tim

Problemi correlati