6

Das Problem ist, dass Kind-Direktive bindet an Eltern aber Syntax {{name}} wird von ng-repeat ignoriert. Was wäre der richtige Weg dies zu erreichen?Angular Direktive/Kind Direktive transclude innerhalb ng-repeat

HTML (Main/Kind-Richtlinie)

<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> 

Richtlinie

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

Richtlinie Vorlage (Module/core/Ansichten/components/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> 

kann ich sehen, dass

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

mit ersetzt erhält

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

und nicht mit

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

Frage: Wie bekomme ich ng-repeat HTML-Bindings-Syntax von Child-Direktive zu respektieren? Oder gibt es einen anderen Weg, dies zu erreichen?

Antwort

8

Wenn ich mich nicht irre, dann versuchen Sie, eine list view so zu erstellen, dass die template der Liste vom Benutzer zur Verfügung gestellt würde, aber die Methoden (Klick, usw.) würden bereits durch die Richtlinie zur Verfügung gestellt werden.

Jetzt, da angular 1.3 ist die transcluded scope ein Kind der directive isolated scope,

so, in Ihrem Fall, wenn Sie die richtige Hierarchie folgen, können Sie die directive scope aus der Vorlage durch den Anwender zugreifen können.

Hier ist Ihr Anwendungsbereich Hierarchie:

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

so, wenn Sie directive scope vom transcluded scope zugreifen möchten, Sie $parent (für ng-Wiederholung) tun müsste und dann item.name zugreifen, wie unten:

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

auch, nicht wahr müssen die Bindungen in Ihrem compact-select-tpl, weil Sie, dass der Inhalt von Einbindung kommen wollen:

<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 ... das ist genial funktioniert gut. Vielen Dank für die Erläuterung des Lebenszyklus des Richtlinienumfangs. – Tim

2

Die displayItemTemplate Direktive, die Sie in die andere Direktive einbinden, hat bereits ihre Daten interpoliert {{name}} und {{item.name}}.

Wenn diese Variablen nicht im $ scope enthalten sind, werden leere Strings innerhalb Ihrer Spannen eingeschlossen.

Dann in Ihrer compactSelect Direktive, wird das div, das übertragen wird, seinen Inhalt außer Kraft gesetzt haben.

Wenn Sie die displayItemTemplate-Anweisung in die Vorlage der anderen Anweisung verschieben, funktioniert die Wiederholung. (Sie müssen ng (transcluden und transcluden entfernen. Wahre

Fiddle

Außerdem, wenn Sie bindToController verwenden, setzen nicht die Attribute innerhalb Umfang

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

Dank ich sehen, wo Sie gehen mit diesem, aber das ist nicht das, was ich achive bin versucht. – Tim