Директива сценария Simple Ng-Repeat (без повторения) TemplateUrl
-
21-12-2019 - |
Вопрос
Закрытие с помощью простой директивы
У меня есть простое замыкание, которое имеет пару свойств hello и items.Когда я привязываю hello world, он работает нормально, но список не отображается, когда я использую ng-repeat.
(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"
};
});
})();
Директива внутри кода
Вот код, который используется для рендеринга пользовательской директивы.Переменная hello отображается правильно, но элементы вообще не отображаются.Если в списке есть один элемент, он отображается.
{{ task.hello }}
<div ng-repeat="item in task.items">
<div> {{ item }} </div>
</div>
Рендеринг изображения
Идентичные струны разрывают цикл
Это кажется неинтуитивным поведением.Попробуй сам.Я изменил одну букву в своем примере, и шаблон отобразился так, как ожидалось.
Может ли кто-нибудь сказать мне, почему это ведет себя так?
Пример кода.Этот код дает разные результаты и по какой-то причине не работает, если вы не добавите префикс «$scope» вместо «this», как в введите описание ссылки здесь.Чтобы еще больше запутать ситуацию, версия с ограниченной областью действия на самом деле не создает проблем, описываемых в этом посте.
Решение
ngRepeat
надеется items
быть разными объектами (сравнивая по ===
).
Поскольку строки являются примитивами, две одинаковые строки считаются равными/идентичными.
Вы можете использовать track by
инструктировать ngRepeat
сравнить что-то еще, например.индексы:
ng-repeat="item in task.items track by $index"
Другие советы
Посмотрите , как ngRepeat
реализуется:
//...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
отслеживает элементы с помощью функции id, которая может быть предоставлена track by
выражение (trackByIdExpFn
), или определяется самой директивой (trackByIdArrayFn
).В этом случае, как вы можете видеть, выражение просто return hashKey(value)
.Это означает, что у вас есть коллизия для идентичных элементов.