Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
何谓$apply&$angularjs中的摘要函数及其用法_Angularjs - Fatal编程技术网

何谓$apply&$angularjs中的摘要函数及其用法

何谓$apply&$angularjs中的摘要函数及其用法,angularjs,Angularjs,$apply和$digest函数之间的区别是什么 有人能解释一下apply、digest函数的确切用法吗?angularjs中的差异以及我们可以使用这些函数的场景吗 //digest function $scope.$digest(); //apply function like this $scope.$apply(function(scope) { scope.demo = "angular"; }); (or) //apply function lik

$apply和$digest函数之间的区别是什么 有人能解释一下apply、digest函数的确切用法吗?angularjs中的差异以及我们可以使用这些函数的场景吗

//digest function
$scope.$digest();

//apply function like this         
$scope.$apply(function(scope)
{
    scope.demo = "angular";
});
     (or)
//apply function like this
$scope.$apply(function()
{
    $scope.demo = "angular";
});
谁能解释一下apply、digest函数的确切用法和angularjs中的差异,以及我们可以使用这些函数的场景

$digest()
  • $scope.$digest()
    函数迭代$scope对象及其子$scope对象(如果有)中的所有监视。当
    $digest()
    迭代手表时,它会为每个手表调用value函数。如果value函数返回的值与上次调用时返回的值不同,则调用该手表的侦听器函数

  • 只要
    AngularJS
    认为有必要,就会调用
    $digest()
    函数。例如,在执行按钮单击处理程序之后,或者在AJAX调用返回之后(在执行了done()/fail()回调函数之后)

  • 您可能会遇到一些特殊情况,AngularJS不为您调用$digest()函数。您通常会通过注意到数据绑定没有更新显示的值来检测到这一点。在这种情况下,调用$scope.$digest()应该可以工作。或者,您也可以使用$scope.$apply(),我将在下一节中对此进行解释


$apply()
  • $scope.$apply()
    函数将函数作为执行的参数,然后在内部调用
    $scope.$digest()
    。这使您更容易确保检查所有手表,从而刷新所有数据绑定。下面是一个
    $apply()
    示例:

    $scope.$apply(函数(){
    $scope.data.myVar=“另一个值”;
    });

  • 作为参数传递给
    $apply()
    函数的函数将更改
    $scope.data.myVar
    的值。当函数退出时,
    AngularJS
    将调用“$scope.$digest()函数,以便检查所有监视值的变化

tl;dr

  • $scope.$digest()
    :对
    $scope
    和子项运行摘要循环
  • $scope.$apply(expr)
    :计算
    expr
    并在
    $rootScope
    上运行摘要循环
很少建议调用
$scope.$digest()
(除非您确实知道自己在做什么),因为它不会将更改传播到
$scope
的子树之外


非常非常简短(因为有大量资源(帖子、教程等)解释了深度上的差异):


$scope
上启动摘要循环,即评估
$scope
的观察者及其子对象的观察表达式,并在必要时执行观察操作。根据需要多次重复此循环,直到所有值稳定(取决于参数)


解析
expr
并在
$scope
的上下文中对其求值。然后它调用
$rootScope.$digest()
,它基本上评估应用程序中的所有观察者(因为每个作用域都是
$rootScope
的子对象)

解析
expr
(使用
$parse
)函数中的结果(或多或少),当使用上下文作为参数(例如作用域)调用函数时,返回在该上下文中计算
expr
的结果。Angular将调用此函数作为上下文传入
$scope
。 如果
expr
已经是一个函数,则不需要实际解析(同样,这可能有点过于简化,但适用于大多数情况)。 另外需要注意的是,在
$apply()
中执行代码会捕获错误,然后通过
$exceptionHandler
(这是一个额外的好处)

一些例子:

// Let there be Scopes...
var scope1 = $rootScope.$new();
var scope2 = $rootScope.$new();
var scope2_1 = scope2.$new();

// Let there be watchers...
$rootScope.$watch(/* RootWatcher */);
scope1.$watch(/* Scope1Watcher */);
scope2.$watch(/* Scope2Watcher */);
scope2_1.$watch(/* Scope2_1Watcher */);

// Let there be `$digest`s...
$rootScope.$digest();   // Evaluates ALL watchers
scope1.$digest();       // Evaluates ONLY Scope1Watcher
scope2.$digest();       // Evaluates BOTH Scope2Watcher, Scope2_1Watcher
scope2_1.$digest();     // Evaluates ONLY Scope2_1Watcher

// Let there be `$apply`s...
$rootScope.$apply();          // Runs $rootScope.$digest()
scope1.$apply();              // Still runs $rootScope.$digest()
scope1.$apply('test = 42');   // Boils down to: scope1.test = 42
    // ...and is equivalent to:
    scope1.$apply(function (scope) { scope.test = 42; });
    // ...which in turn is equivalent to:
    scope1.$apply(function (ignored) { scope1.test = 42; });

// So, I could have a reusable function:
var assign42 = function (scope) { scope.test = 42; };
scope1.$apply(assign42);     // Boils down to: scope1.test = 42;
scope2.$apply(assign42);     // Boils down to: scope2.test = 42;
scope2_1.$apply(assign42);   // Boils down to: scope2_1.test = 42;
$apply()
另一个值得注意的地方是捕捉错误并将其传递给Angular(这是一件好事)。例如:


不用说,Angular(如果使用得当)将为您处理摘要生命周期,因此您不必手动调用
$digest()
/
$apply()
。 例外情况是绑定到DOM元素的事件处理程序和在Angular上下文之外运行的第三方代码中的回调。
这在文档中也有很好的解释:,

检查任何绑定值是否已更改的步骤实际上有一个方法,
$scope.$digest()
。这就是神奇发生的地方,但我们几乎从不直接调用它,而是使用
$scope.$apply()
为您调用$scope.$digest()

$scope.$apply()
获取函数或角度表达式字符串并执行它,然后调用
$scope.$digest()
以更新任何绑定或观察程序

那么,什么时候需要调用$apply()

实际上很少。AngularJS实际上在$apply调用中调用了几乎所有的代码。像
ng click
、控制器初始化、
$http
回调之类的事件都包装在
$scope.$apply()
中。所以你不需要自己称呼它,事实上你不能。在$apply内调用
$apply
将抛出错误

如果要在新一轮中运行代码,您确实需要使用它。而且只有在这个转折点不是从AngularJS库中的方法创建的情况下。在新回合中,您应该将代码包装在
$scope.$apply()
中。这里有一个例子。我们正在使用setTimeout,它将在延迟后的新回合中执行一个函数。由于Angular不知道该新转向,因此不会反映更新

function Ctrl($scope) {
  $scope.message = "Waiting 2000ms for update";

    setTimeout(function () {
        $scope.$apply(function () {
            $scope.message = "Timeout called!";
        });
    }, 2000);
}

回答不错,但不管是善意还是错误:)
$scope.$apply()
不一定需要函数(例如,它可以
// Let there be Scopes...
var scope1 = $rootScope.$new();
var scope2 = $rootScope.$new();
var scope2_1 = scope2.$new();

// Let there be watchers...
$rootScope.$watch(/* RootWatcher */);
scope1.$watch(/* Scope1Watcher */);
scope2.$watch(/* Scope2Watcher */);
scope2_1.$watch(/* Scope2_1Watcher */);

// Let there be `$digest`s...
$rootScope.$digest();   // Evaluates ALL watchers
scope1.$digest();       // Evaluates ONLY Scope1Watcher
scope2.$digest();       // Evaluates BOTH Scope2Watcher, Scope2_1Watcher
scope2_1.$digest();     // Evaluates ONLY Scope2_1Watcher

// Let there be `$apply`s...
$rootScope.$apply();          // Runs $rootScope.$digest()
scope1.$apply();              // Still runs $rootScope.$digest()
scope1.$apply('test = 42');   // Boils down to: scope1.test = 42
    // ...and is equivalent to:
    scope1.$apply(function (scope) { scope.test = 42; });
    // ...which in turn is equivalent to:
    scope1.$apply(function (ignored) { scope1.test = 42; });

// So, I could have a reusable function:
var assign42 = function (scope) { scope.test = 42; };
scope1.$apply(assign42);     // Boils down to: scope1.test = 42;
scope2.$apply(assign42);     // Boils down to: scope2.test = 42;
scope2_1.$apply(assign42);   // Boils down to: scope2_1.test = 42;
// BAD - Avoid doing this:
somePossiblyErrorThrowingFunc();
scope.$apply();

// GOOD - Do this instead:
scope.$apply(somePossiblyErrorThrowingFunc);
function Ctrl($scope) {
  $scope.message = "Waiting 2000ms for update";

    setTimeout(function () {
        $scope.$apply(function () {
            $scope.message = "Timeout called!";
        });
    }, 2000);
}