Einfache Ng-Repeat (nicht wiederholende) Szenario-Direktive templateUrl
-
21-12-2019 - |
Frage
Schließung mit einfacher Direktive
Ich habe einen einfachen Verschluss, der ein paar Eigenschaften hallo und Gegenstände hat.Wenn ich binde, funktioniert die Hallo-Welt einwandfrei, aber die Liste wird nicht gerendert, wenn ich ng-repeat verwende.
(function() {
var app = angular.module('safety-plus-task-list', []);
app.directive('taskList', function () {
return {
restrict: "E",
templateUrl: "/Task/TaskList",
scope: {
},
controller: function ($http, $scope, $element, $attrs) {
this.hello = "HELLO WORLD";
this.items = [
"gravida nisl, id fringilla neque ante vel mi.",
"quam gravida nisl, id fringilla neque ante vel mi."];
},
controllerAs: "task"
};
});
})();
Code innerhalb der Direktive
Hier ist der Code, der zum Rendern der benutzerdefinierten Direktive verwendet wird.Die Variable hello wird korrekt angezeigt, aber Elemente werden überhaupt nicht gerendert.Wenn es ein Element in der Liste gibt, wird es angezeigt.
{{ task.hello }}
<div ng-repeat="item in task.items">
<div> {{ item }} </div>
</div>
Gerendertes Bild
Identische Saiten brechen die Schleife
Dies scheint ein unintuitives Verhalten zu sein.Probieren Sie es selbst aus.Ich habe einen Buchstaben aus meinem Beispiel geändert und die Vorlage wie erwartet gerendert.
Kann mir jemand sagen, warum sich das so verhält?
Beispiel des Kodex.Dieser Code führt zu unterschiedlichen Ergebnissen und funktioniert aus irgendeinem Grund nur, wenn Sie das Präfix "$ scope" anstelle von "this" wie in hinzufügen linkbeschreibung hier eingeben.Um die Dinge verwirrender zu machen, erzeugt die Bereichsversion tatsächlich nicht das Problem, das in diesem Beitrag beschrieben wird.
Lösung
ngRepeat
erwarten items
verschiedene Objekte sein (Vergleichen mit ===
).
Da Strings Primitive sind, werden 2 gleiche Strings als gleich / identisch betrachtet.
Sie können verwenden track by
anweisen ngRepeat
um etwas anderes zu vergleichen, z.Index:
ng-repeat="item in task.items track by $index"
Andere Tipps
Schau dir an, wie ngRepeat
ist implementiert:
//...at line 225
if (trackByExp) {
trackByExpGetter = $parse(trackByExp);
trackByIdExpFn = function(key, value, index) {
// assign key, value, and $index to the locals so that they can be used in
hash functions
if (keyIdentifier) hashFnLocals[keyIdentifier] = key;
hashFnLocals[valueIdentifier] = value;
hashFnLocals.$index = index;
return trackByExpGetter($scope, hashFnLocals);
};
} else {
trackByIdArrayFn = function(key, value) {
return hashKey(value);
};
}
//...at line 289
trackByIdFn = trackByIdExpFn || trackByIdArrayFn;
ngRepeat
verfolgt Elemente durch eine ID-Funktion, die von der bereitgestellt werden kann track by
Ausdruck (trackByIdExpFn
) oder durch die Richtlinie selbst festgelegt wird (trackByIdArrayFn
).In diesem Fall lautet der Ausdruck, wie Sie sehen, einfach return hashKey(value)
.Dies bedeutet, dass Sie eine Kollision für identische Elemente haben.