角度ui-router视图的控制器是否导致$ scope。$ watch不要开火?

时间:2015-01-19 23:17:22

标签: angularjs angular-ui-router

要解释此问题,请查看以下states

.state('app.play.lobby', {
            url: '/lobby',
            resolve: {
                games: function (FirebaseAdapter) {
                    return FirebaseAdapter
                        .syncArray('disciplines')
                        .$loaded()
                        .then(function (list) {
                            return list;
                        });
                },
                tournaments: function (FirebaseAdapter) {
                    return FirebaseAdapter
                        .syncArray('tournaments')
                        .$loaded()
                        .then(function (list) {
                            return list;
                        });
                }
            },
            views: {
                filter: {
                    templateUrl: 'play/lobby/filter.tpl.html',
                    controller: LobbyFilterController
                },
                browser: {
                    templateUrl: 'play/lobby/browser.tpl.html',
                    controller: LobbyBrowserController
                }
            }
        });

一切都很好。问题是:在控制器LobbyFilterController中,我使用$scope.$watch()来监听对象的更改。但是 $watch()命令只被触发一次,这是在状态成功加载之后。加载状态后我立即更改对象内的属性值,没有任何反应。

LobbyFilterController

function LobbyFilterController($scope, games, TournamentFilter) {
    $scope.filter = {
        game: null,
        mode: 'regular',
        type: 'all',
        format: 'all',
        eliminationMode: 'all',
        gridsize: 'all',
        status: 'all',
        groupstage: false,
        reshuffledGrid: false,
        password: false
    };

    $scope.$watch($scope.filter, function(data) {
        console.log('filter changed...');
    }, true);
}

当我尝试使用普通值(例如$ scope.myVar)时,此行为不会发生变化。由于事件在加载后发生一次,我猜我没有犯错(希望我错了)?

1 个答案:

答案 0 :(得分:0)

您需要提供观看属性(或watch expression)作为字符串或返回值的函数表达式。相反,你正在设置一个对象。尝试将其更改为:

$scope.$watch('filter', function(data) {
    console.log('filter changed...');
}, true);

$ watch使用$parse to create从提供的表达式中获取getter。而你提供的是一个对象作为表达式,它只会被忽略,因为它只查找字符串或函数。看看case statements at the source。所有的观察者都会至少开火一次,以便在你的情况下在摘要周期中启动脏检查,如果你在第一次执行中查找参数,你会看到两个值都是未定义的,因为没有真正看过或者观察者总是会使用被覆盖的angular.noop函数返回undefined