Angular JS распространяет переменную переменной дочернего объекта в родительскую область
Как я могу принимать переменные изменения и легко распространять их обратно в ParentCtrl, несмотря на "новый" var, созданный в ChildCtrl? Дополнительные очки для минимальных и не $$ и $watch (упрощают их реализацию)
ParentCtrl
My ChildCtrl достаточно разный, где я не могу легко абстрагироваться от макета и ng-view, но все они зависят от тех же функций в ParentCtrl.
$scope.searchTerms определяется в ParentCtrl, но поле ввода с ng-model = 'searchTerms' находится в представлении дочерних контроллеров. Когда этот var изменяет, он не отражается в ParentCtrl только ChildCtrls.
Пример:
http://jsfiddle.net/JHwxP/22/
HTML Partial
<div ng-app>
<div ng-controller="Parent">
parentX = {{x}} <br/>
parentY = {{y}}<br/>
<div ng-controller="Child">
childX = {{x}}<br/>
childY = {{y}}<br/>
<a ng-click="modifyBothScopes()">modifyBothScopes</a><br>
<br>
The changes here need to appear in 'Parent'. <input ng-model='y'>
</div>
</div>
</div>
Контроллеры
function Parent($scope) {
$scope.x= 5;
$scope.y= 5;
}
function Child($scope) {
$scope.modifyBothScopes= function() {
$scope.$parent.x++;
};
}
ОБНОВЛЕНИЕ
В настоящее время я пытаюсь использовать общий сервис: https://gist.github.com/exclsr/3595424
ОБНОВЛЕНИЕ
Попытка испускать/широковещательную систему
РЕШИТЬ
Проблема:
Я сохранял $scope.searchTerms в родительском и при изменении создавал пробел в области child $.
Решение:
Я должен был сделать $scope.search.terms в родительском, а когда он изменился в ребёнке, он будет пузыриться до родителя.
Пример: http://jsfiddle.net/JHwxP/23/
Ответы
Ответ 1
Это связано с тем, как работает прототипное наследование.
Когда вы запрашиваете $scope.x
в дочернем контроллере, он проверяет, определена ли x в его области, а если нет, ищет x в родительской области.
Если вы назначаете свойство дочерней области x
, оно изменяет только область содержимого.
Простой способ справиться с этим и получить совместное поведение - использовать объект или массив.
function ParentCtrl($scope) {
$scope.model = {x: 5, y: 5};
}
function ChildCtrl($scope) {
$scope.update = function(x, y) {
$scope.model.x = x;
$scope.model.y = y;
};
}
Здесь изменения будут видны в обеих областях, потому что $scope.model
будет ссылаться на один и тот же объект как в родительских, так и в дочерних областях.
Джон Линдквист имеет видео в этом.
Ответ 2
Другим решением, которое не связано с созданием связки объектов для передачи по ссылке, является создание функций setter в родительском контроллере.
function ParentCtrl($scope) {
$scope.x = 5;
$scope.y = 5;
$scope.setX = function(value) {
$scope.x = value;
}
$scope.setY = function(value) {
$scope.y = value;
}
}
function ChildCtrl($scope) {
$scope.update = function(x, y) {
$scope.setX(x);
$scope.setY(y);
};
}
Я считаю, что это чище, когда не может быть смысла, чтобы данные были частью одного и того же объекта.
Вы также можете сходить с ума и сделать что-то подобное в ребенке:
function ChildCtrl($scope) {
var superSetX = $scope.setX;
$scope.setX = function(value) {
superSetX(value * 2);
};
...
}
Ответ 3
Я искал что-то вроде этого. Первое решение появилось после чтения этого. Вы можете совместно использовать родительскую модель с дочерним контроллером.
Вот пример. Я даже использую массив элементов, чтобы доказать свою точку зрения. ChildController меняет своего родителя, так как все они являются частью одной и той же вселенной.