在控制器之间切换,无法更新视图

时间:2015-04-07 00:19:16

标签: javascript angularjs model-view-controller

在下面的示例待办事项列表中,您可以通过按蓝色添加按钮添加项目,并使用删除按钮删除带有复选标记的项目。

但是,删除任何项目后,添加项目不会更新视图。我怀疑我的麻烦在于让两个控制器访问todos变量。

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 = [];



})();

1 个答案:

答案 0 :(得分:1)

一开始,主控制器和DialogController中的$ scope.todos都指向&#34; todo&#34;数组,因此它可以在您添加新项目时显示。

在clearComplete函数中,$ scope.todos现在指向另一个数组,而Dialog控制器中的$ scope.todos仍然指向&#34; todo&#34;数组,所以当&#34; todo&#34;数组是更新,主控制器中的$ scope.todos保持不变。

将clearComplete的代码更改为:

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

顺便说一下,对此的一个优化解决方案应该是:使用$ rootscope和广播。更改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();
    };
}

然后在主控制器中捕获事件:

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

                //other codes

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