Как я могу обновить массив parentScope, когда он изменяется в childScope в Angular?
У меня есть основной контроллер с вложенным дочерним контроллером
<div class='main' ng-controller='mainController'>
<div class='search' ng-controller='searchController'>
<input type='text' ng-model='keyword'>
<button ng-click='search(keyword)'>Search!</button
</div>
</div>
В моем главном контроллере я пытаюсь создать переменную главной области для хранения результатов поиска.
var app = angular.module('mapApp', [])
.controller('mainController', [
'$scope',
'$searchFactory',
($scope, searchFactory)=>{
$scope.results = [];
$scope.$watchCollection('results', (newVal, oldVal)=>{
console.log('results updated to, ', newVal);
}, true);
}]);
Затем я пытаюсь обновить основной контроллер $scope.results
переменная в моем дочернем контроллере.
app.controller('searchController', ['$scope', 'searchFactory', ($scope, searchFactory)=>{
$scope.search = function(keyword, type){
let request = {
location: $scope.location,
radius: '500',
type: type ? type : undefined,
keyword: keyword
};
searchFactory.search(request, (result)=>{
console.log('result from search was', result);
$scope.results = result;
});
};
}]);
мой $watch
функция не вызывается, что я считаю, потому что $scope.results
не обновляется. Я пытался использовать три типа $watch
функции, как показано в Angular Docs в разделе глубины $scope.watch. Я прочитал эту статью о переходе на стиль наследования прототипов для областей, но я не уверен, что это лучший способ решить мою проблему, потому что я не уверен, что иду по правильному пути. Возможно, мне следует вместо этого использовать источники событий / вещатели, чтобы достичь желаемого эффекта?
Как я могу обновить results
переменная в searchController
родительская область (mainController
) так что я могу иметь доступ к нему братьев и сестер searchController
?
РЕДАКТИРОВАТЬ / РЕШЕНО Итак, это действительно странно, и если вы можете объяснить, почему это так, золотая звезда для вас.
Вот mainController, когда код не работает:
.controller('mainController', [
'$scope',
'searchFactory',
($scope,searchFactory)=>{
$scope.searchData = {results:[]};
$scope.setResults = function(newResults){
$scope.searchData.results = newResults;
console.log('new results is', $scope.searchData.results);
};
//this function doesn't invoke except on initiation
$scope.$watch('searchData.results', (newVal, oldVal)=>{
console.log('results updated to, ', newVal);
}, true);
}]);
Вот mainController, когда код работает:
.controller('mainController', [
'$scope',
'searchFactory',
($scope,searchFactory)=>{
$scope.searchData = {results:[]};
//comment out the evil console log and... it works??!!
$scope.setResults = function(newResults){
$scope.searchData.results = newResults;
//console.log('new results is', $scope.searchData.results);
};
//this invokes now, because black magic?
$scope.$watch('searchData.results', (newVal, oldVal)=>{
console.log('results updated to, ', newVal);
}, true);
}]);
Зачем...
1 ответ
С помощью $scope.results = result;
устанавливает новое свойство результатов в дочерней области, которое скрывает свойство результатов родителя.
Чтобы исправить эту проблему, вы можете использовать объект для хранения свойства результатов:
$scope.searchData = {results: []};
$scope.$watchCollection('searchData.results', (newVal, oldVal)=>{
console.log('results updated to, ', newVal);
}, true);
и тогда в вашем дочернем контроллере установите только это свойство:
$scope.searchData.results = result;