фона
Я пытаюсь построить AngularJS директивы с 2 путем, связанной изолят областью видимости собственностью. Эта директива должна мутировать данные в массив, чтобы иметь возможность правильно отображать его с помощью ng-repeat
. Я знаю, что бесконечный цикл дайджеста произойдет, когда вы вернете новый массив из функции get, потому что это новый массив, и AngularJS будет продолжать рассматривать модель неустойчивой и продолжать переваривать.AngularJS директивы мутировать изолят данные областей
Эта проблема может быть решена путем использования функции «get» для возврата нового массива ... но это не вариант для меня, потому что мне нужно, чтобы измененный массив изменялся всякий раз, когда изменяется исходный массив. Это функция, предоставляемая областью выделения, и я бы не хотел использовать $scope.$watch()
, потому что это потребовало бы, чтобы я ввел $scope
, из чего я пытаюсь избавиться, используя синтаксис bindToController: true
.
Вопрос
Так что мой вопрос, учитывая фон выше: Что такое правильный способ мутирует изолят данные областей внутри AngularJS директивы?
Код
в Jsfiddle: link (обратите внимание на бесконечную переваривать ошибку цикла, когда вы открываете консоль инструментов разработчика)
HTML:
<div ng-app="IsolateScopeExample" ng-controller="MainController as vm">
<h4>Original data</h4>
{{vm.dataToMutate}}
<h4>Mutated data</h4>
<div mutator data="vm.dataToMutate"></div>
</div>
Javascript (AngularJS версия: 1.3.14) :
angular.module('IsolateScopeExample', [])
.controller('MainController', function(){
this.dataToMutate = [{a: 1},{a: 2},{a: 3}];
})
.directive('mutator', function(){
return {
scope: {
data: '=',
},
template: '<span ng-repeat="item in mvm.mutateData()">{{item}}</span>',
bindToController: true,
controller: function(){
this.mutateData = function(){
console.log('Mutating');
var newData = [];
this.data.forEach(function(d){newData.push({b: d.a + 1});});
return newData;
};
},
controllerAs: 'mvm'
};
});
Он не нужен или даже нежелательным, что директива мутирует исходную ссылку на данные. Просто нужно изменить данные для своей собственной области (например, создав новый массив), но оставить исходный массив таким, какой он есть. –
@YanikCeulemans О, так что это похоже на вычислительную собственность. Вы можете посмотреть исходный массив, а затем создать другой массив в области директивы, содержащий пересчитанные данные. Затем запустите шаблон директивы. Вот пример: https://jsfiddle.net/b7ekv4tm/3/ Не совсем уверен, почему вы избегаете смотреть. – Joseph
Да, это точно как вычисленное свойство. Причина, по которой я пытаюсь избежать использования '$ scope', заключается в том, что я пытаюсь использовать синтаксис bindToController для AngularJS 1.3+ (который предотвращает общие проблемы деконфигурации данных с родительскими иерархиями' $ scope', как объясняется в статье, связанной Xeon в другом ответе). Этот новый синтаксис должен позаботиться о том, чтобы автоматически обновлять атрибуты директивы, связанные с двумя способами, на свой контроллер. Необходимость использовать '$ scope' для просмотра всех свойств с двумя способами связана с громоздкой, когда мы имеем дело не только с одним свойством. –