简体   繁体   中英

switching between controllers, can't update view

In the example todo list below, you can add an item by pressing the blue add button, and remove checkmarked items with the delete button.

However, once you delete any items, adding items does not update the view. I suspect my trouble lies in having two controllers accessing the todos variable.

DEMO

(function(){
'use strict';

angular.module('todoApp', ['ngMaterial', 'ngAnimate', 'ngAria' ])

    .directive('mainApp', function(){
        return {
            restrict: 'E',
            templateUrl: 'app.html',
            controller: function($scope, $mdDialog){
                $scope.todos = todos;

                $scope.someCompleted = function(){
                    for (var i = 0; i < $scope.todos.length; i++) {
                        if ($scope.todos[i].done === true) {
                            return true;
                        }
                    }
                };
                $scope.clearCompleted = function(){
                    $scope.todos = $scope.todos.filter(function(item){
                        return !item.done;
                    });
                };
                $scope.showAdvanced = function(ev) {
                    $mdDialog.show({
                        controller: DialogController,
                        templateUrl: 'addDialog.html',
                        targetEvent: ev,
                    });
                };

            },
            controlerAs: 'list'
        };

    })

;
function DialogController($scope, $mdDialog) {
    $scope.todos = todos;
    $scope.hide = function() {
        $mdDialog.hide();
    };
    $scope.cancel = function() {
        $mdDialog.cancel();
    };
    $scope.answer = function(answer) {
        $mdDialog.hide(answer);
    };
    $scope.addTodo = function(){
        $scope.todos.push({name: $scope.newTodo, done: false});
        $scope.newTodo = null;
        $mdDialog.hide();
    };
}

var todos = [];



})();

In the beginning, both the $scope.todos in main controller and DialogController point to the "todo" array, so it can display when you add new item.

In the clearComplete function, the $scope.todos now point to another array, while the $scope.todos in Dialog controller still point to the "todo" array, so when the "todo" array is update, the $scope.todos in main controller remain unchanged.

Change the code of the clearComplete into this:

$scope.clearCompleted = function(){
    todos = todos.filter(function(item){return !item.done;});
    $scope.todos = todo; //It might run without this line, just to make sure
};

By the way, an elegent solution for this should be: Using the $rootscope and broadcast. Change the code of your DialogController:

function DialogController($scope, $mdDialog, $rootScope) {
    //$scope.todos = todos; //Remove this line

    $scope.addTodo = function(){
        //Broadcast an event, main controller will catch this
        $rootScope.$broadcast("NoteAdded", {name: $scope.newTodo, done: false});
        $scope.newTodo = null;
        $mdDialog.hide();
    };
}

Then catch the event in the main controller:

controller: function($scope, $mdDialog){
                $scope.todos = todos;

                //other codes

                $scope.$on("NoteAdded", function(event, item){
                       $scope.todos.push(item);
                });     
            }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM