$ watch on rootscope不工作,棱角分明

Joe*_*Joe 3 javascript angularjs

我有一个切换管理员和客户端模式的按钮.我把它放在了rootcope上,所以我可以随处访问它.

我正在使用angular-ui directive切换.

我已经看了这个型号.但什么都没发生.知道什么可能是错的吗?

.run(['$rootScope', '$state', '$stateParams', '$location',
     function ($rootScope, $state, $stateParams, $location) {

         $rootScope.projectMode = 'Client';

         $rootScope.$watch('projectMode', function(){
             var path = $location.path();
             alert("fire") //Only fire ones when the app starts
             if($rootScope.projectMode === 'Client'){
                 var current = 'client'
                 var replace = 'admin'
             } else {
                 var current = 'admin'
                 var replace = 'client'
             }
             var newUrl = path.replace(current, replace)
             $location.url(newUrl);
         })

    }])
Run Code Online (Sandbox Code Playgroud)

这是我的看法.

<div class="btn-group">
  <button type="button" class="btn btn-default"  ng-model="projectMode" btn-radio="'Client'">Klient</button>
  <button type="button" class="btn btn-default"  ng-model="projectMode" btn-radio="'Admin'">Admin</button>
</div>
Run Code Online (Sandbox Code Playgroud)

btn-radio 是用于切换的angular-ui指令.

我已经检查过它$rootScope.projectMode正在改变.所以它一定是错的$watch.

Luk*_*kas 8

真正的问题是,projectMode在你看来是不一样projectMode$rootScope.这是人们在Angular中遇到的常见问题.

Angular中的范围是典型的.如果在当前作用域中找不到属性,则它会在该作用域的父级中查找具有相同名称的属性,依此类推,直到达到该属性$rootScope.因此,当您的视图初始化时,可能看起来projectMode就是您初始化它的任何内容$rootScope.

但是,只要更改了值projectMode,它就会在控制器的命名范围上创建一个新值,该值projectMode不同于$rootScope.projectMode.因此,有意义的是你$watch没有被解雇...... $rootScope值没有改变,只有控制器范围的值正在改变.

如果您想修复它,只需更改projectMode$root.projectModeHTML中的任何位置即可.($rootHTML内部是你引用的方式$rootScope.)


小智 6

$ watch有一个鲜为人知的第三个选项,它检查对象的相等性而不是对象引用.将其设置为true.试试这个,

$rootScope.$watch('projectMode', function(){
 ...your stuff here
}, true);
Run Code Online (Sandbox Code Playgroud)