我来自Knockout,我试图了解Angular如何更新范围。关于为什么在范围上定义的函数(例如$scope.doStuff = function()
)在每个范围刷新时都会被执行,我感到有点困惑。
Plnkr链接:http://plnkr.co/edit/YnvOELGkRbHOovAWPIpF?p=preview
例如:
HTML
<div ng-controller="one">
<input type="text" ng-model="a">
{{b()}}
</div>
JS
angular.module('test', [])
.controller('one', ['$scope', function ($scope) {
$scope.a = 'one';
$scope.b = function () {
console.log('b has executed');
}
}])
因此,只要在$scope.a
的输入表单字段中发生事件,就会执行函数$scope.b
。为什么会这样?该函数没有依赖关系,它始终刷新似乎效率低下。
如果我在同一个结构中添加另一个控制器,如:
HTML
<div ng-controller="one">
<input type="text" ng-model="a">
{{b()}}
</div>
<div ng-controller="two">
<input type="text" ng-model="x">
{{y()}}
</div>
JS
angular.module('test', [])
.controller('one', ['$scope', function ($scope) {
$scope.a = 'one';
$scope.b = function () {
console.log('b has executed');
}
}])
.controller('two', ['$scope', function ($scope) {
$scope.x = 'two';
$scope.y = function () {
console.log('y has executed');
}
}])
每当我更新控制器$scope.a
中的one
时,输出为:
b has executed
y has executed
为什么控制器two
正在执行$scope.y
?我认为创建一个新的控制器会创建一个新的子范围。是因为子范围与父范围相关联吗?
更有趣的是,如果我更新控制器$scope.x
中的two
,则输出为:
b has executed
y has executed
b has executed <-- a second time... what?
为什么函数$scope.b
第二次执行?
那么为什么Angular中的函数会在每个范围刷新时执行?
答案 0 :(得分:3)
Angular使用所谓的脏检查。为了维护视图和控制器之间的绑定,必须验证与函数关联的任何变量。
使用你所演示的内容通常是一个坏主意,可以影响中型到大型应用程序的性能。
使用固定变量绑定到视图并在需要时进行更改时,这将导致整体性能更高,并且仅重新渲染已更改的部分。
一般情况下,你不从视图中“调用”该函数,但有时这是在ng-repeat中使用动态数据的唯一方法然后我会将该数据放入一个对象/数组并返回该对象/数组,然后甚至角度将继续在其摘要周期上调用该函数,如果不更改它将不会“更新”视图。
答案 1 :(得分:2)
在这里我这么认为,每次页面加载时,angular js都会启动该功能,这意味着每次页面加载都会被执行,所以改为直接调用,使用ng-change调用它。
<div ng-controller="one">
<input type="text" ng-model="a" ng-change=b()>
</div>
<div ng-controller="two">
<input type="text" ng-model="x" ng-change=y()>
</div>
在控制器中,您可以将该功能分配给您所需的ng模型,如下所示,
angular.module('test', [])
.controller('one', ['$scope', function ($scope) {
$scope.b = function () {
$scope.a = 'one';
console.log('b has executed');
}
}])
.controller('two', ['$scope', function ($scope) {
$scope.y = function () {
$scope.x = 'two';
console.log('y has executed');
}
}])
或者您也可以通过分配ng-model将函数值返回到ng-model,它将给出正确答案而不是每次调用。
答案 2 :(得分:1)
只是因为无法知道函数的所有依赖项是什么。假设您的函数b
(在控制器one
上)将是这样的:
$scope.b = function () {
console.log('b has executed');
another_func($scope);
}
并且函数another_func
的定义如下:
function another_func (obj) {
obj.a = 'something';
return obj.a;
}
如何以编程方式知道函数$scope.b
会调用一个函数来调用另一个函数来获取依赖于$scope.a
的值?