AngularJS中为何需用函数返回求和结果?赋值不更新问题咨询
嘿,这问题其实是AngularJS的脏检查机制在背后起作用,我给你拆解清楚:
先看你的两种写法差异:
第一种能正常更新的原因
你写的{{result()}},每次Angular执行脏检查(比如用户输入完内容、触发了某个事件)的时候,它都会调用这个result()函数。函数内部会去读取$scope.firstNumber和$scope.secondNumber这两个绑定到输入框的变量——只要这两个值变了,函数返回的结果就会跟着变,视图自然就同步更新了。
第二种不更新的核心问题
而$scope.result = $scope.firstNumber + $scope.secondNumber;这行代码,只在控制器初始化的时候执行一次!它把当时两个数的和(也就是0+0=0)赋值给了$scope.result,之后哪怕你修改输入框里的数字,也没有任何代码会重新计算firstNumber + secondNumber并更新result的值。所以视图里的{{result}}就一直停留在初始化的0,不会跟着变。
解决方法
这里给你几种常用的方案:
继续使用函数调用的方式(就是你第一种写法),简单直接,适合这种简单的计算场景。
用
$watchGroup监听变量变化
如果你不想在视图里调用函数,可以手动监听firstNumber和secondNumber的变化,一旦它们变了就重新计算result:var app = angular.module('myApp', []); app.controller('myCtrl', function($scope) { $scope.firstNumber = 0 ; $scope.secondNumber = 0; // 监听两个变量的变化,更新result $scope.$watchGroup(['firstNumber', 'secondNumber'], function(newValues) { $scope.result = newValues[0] + newValues[1]; }); });这样每次输入框的值变化,watch的回调就会触发,自动更新
result,视图也会同步。使用计算属性(AngularJS 1.3+)
如果你想用更优雅的方式(类似Vue的计算属性),可以结合controllerAs语法和Object.defineProperty来实现:<div ng-app="myApp" ng-controller="myCtrl as vm"> First Number: <input type="number" ng-model="vm.firstNumber"><br> Last Number: <input type="number" ng-model="vm.secondNumber"><br> <br> Sum: {{vm.result}} </div> <script> var app = angular.module('myApp', []); app.controller('myCtrl', function() { var vm = this; vm.firstNumber = 0 ; vm.secondNumber = 0; // 定义计算属性result,每次访问都会重新计算 Object.defineProperty(vm, 'result', { get: function() { return vm.firstNumber + vm.secondNumber; } }); }); </script>这种方式不需要手动写watch,每次视图访问
vm.result时都会自动计算最新的值。
总结一下
AngularJS不会自动追踪普通变量的依赖关系,直接赋值的$scope.result是静态值,只有初始化时计算一次;而函数调用、watch监听或者计算属性,都会在依赖的变量变化时重新计算结果,所以能让视图实时更新。
内容的提问来源于stack exchange,提问作者Prabin Upreti

