【问题标题】:Angular watch doesn't work with controllerAs syntaxAngular 手表不适用于 controllerAs 语法
【发布时间】:2016-10-16 07:02:25
【问题描述】:

观看回复时遇到问题。

我有一个 SettingsCtrl 作为设置,这是我的观点:

<input  type="text" class="form-control" ng-model="settings.test.one"  />
<input  type="text" class="form-control" ng-model="settings.test.second"  />

这是我的控制器:

app.controller('SettingsCtrl', function ($scope, settingsFactory, Test) {
  
  var vm = this;
  
  
  settingsFactory.test().then(function(response){
  
     vm.test = response;
  })
  
  /////  OR
  
  vm.test = Test; // this is from ui-router resolve
  
  
    $scope.$watch(angular.bind('vm', function () {
    return vm.test;
    }), function (newV, oldV) {
    console.log(newV, oldV); 
    });
  
    $scope.$watch(function watch(scope){
     return vm.test;
    }), function handle(newV, oldV) {
    console.log(newV, oldV);
    });
  
    $scope.$watch('vm', function (newVal, oldVal) {
        console.log('newVal, oldVal', newVal, oldVal);
    });
  
  });

我一直在搜索并找到了不同的解决方案,但它们都不起作用。

**** 它只是第一次观看,当控制器被加载并且我看到我的控制台日志时,但是当我尝试进行更改时,观察者什么也不做。

我做错了什么?

【问题讨论】:

    标签: javascript angularjs watch angularjs-controlleras


    【解决方案1】:

    在参考 github 帖子 (https://github.com/johnpapa/angular-styleguide/issues/428) 和 (http://jsbin.com/levewagufo/edit?html,js,console,output) 后,对我有用的方法是将控制器从 vm = this 重命名为(在你的情况下) settings = this 在编写控制器的开头。这可以确保引用与视图中的“控制器为”声明相匹配。希望这会有所帮助

    在视图中:

    ng-controller="AddDetailController as addDetailsCtrl"
    

    在控制器 Js 文件中:

     $scope.$watch('addDetailsCtrl.currentPage', function (current, original) {
            console.log(current + ":" + original);    });
    

    【讨论】:

      【解决方案2】:

      AngularJS 仍然按预期工作:

      angular
        .module('app', [])
        .controller('SettingsCtrl', function($scope) {
      
          var vm = this
      
          vm.test = ''
      
      
          $scope.$watch(function watch(scope) {
              return vm.test;
            },
            function handle(newV, oldV) {
              if (newV && newV.name && newV.name !== oldV.name) {
                vm.test.watchedName = newV.name.toUpperCase()
              }
            }, true);
        });
      <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
      
      <div ng-app='app'>
        <div ng-controller='SettingsCtrl as settings'>
          <input type='text' ng-model='settings.test.name' />
          <pre><code>
       {{ settings.test.watchedName }}
       </code></pre>
        </div>
      </div>

      【讨论】:

        【解决方案3】:

        如果我没记错的话,你的 $watch 是在第一次加载控制器时被击中,但不是在你改变对象中的某些内容时。如果这是真的,那么试试这个:

        $scope.$watch('vm', function (newVal, oldVal) {
            console.log('newVal, oldVal', newVal, oldVal);
        }, true);
        

        默认情况下,$watch 函数会监视引用,因此如果您只更改被监视对象的属性,它将不会被触发。通过在末尾添加true,您将开始深入观察,并且每次更改对象的属性时都会受到打击。

        【讨论】:

        • 非常感谢!我忘记了深入观看。有帮助。
        【解决方案4】:

        尝试以下代码进行观看。

         $scope.$watch(function(){
            return ctrl.test;
        },function(newVal,oldVal){
            console.log(newVal,oldVal);
        },true)
        

        这是工作的fiddle

        您需要对物体进行深入观察。

        此链接$watch an object 将帮助您理解这一点。

        【讨论】:

        • 感谢您的回答,但首先是另一个回答者,这就是为什么我标记了这个答案,对不起,但无论如何谢谢
        【解决方案5】:

        请尝试在 watcher 中调用 vm 变量为 controller.vmVariable。 Controller 是您的控制器名称,然后是您在 vm 中分配的变量。

        $scope.$watch('controller.vmVariable', function (newVal, oldVal) {
            console.log('newVal, oldVal', newVal, oldVal);
        });
        

        【讨论】:

        • 像这样: $scope.$watch('SettingsCtrl.test', ... ) ?没什么:(
        • 在路由中为控制器指定了一些名称,对吗?在“controllerAs”字段中。你能试试吗?
        • 我已经尝试过了:SettingsCtrl as settings - $scope.$watch('settings.wm', ... ) Nothing
        • 但是!当控制器启动时,所有解决方案仅在第一次启动时启动。但对变化没有反应。也许还有其他问题?
        猜你喜欢
        • 2017-08-05
        • 2016-07-14
        • 1970-01-01
        • 2021-07-13
        • 2017-09-05
        • 2016-06-03
        • 2016-04-04
        • 1970-01-01
        • 2014-10-08
        相关资源
        最近更新 更多