Как я могу обновить массив 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;
Другие вопросы по тегам