gpt4 book ai didi

angularjs - 与函数的指令绑定(bind)最终出现在 $digest 循环中 - 错误 : $rootScope:infdig

转载 作者:行者123 更新时间:2023-12-02 20:44:24 24 4
gpt4 key购买 nike

我想要一个与对象列表一起使用的指令,但我还需要接受 2 路绑定(bind)或函数绑定(bind)。

app.directive('myDir', function() {
return {
scope: {
list: "=?",
list_func: "&?listFunc"
},

controller: ['$scope', function($scope) {
$scope.get_list = function() {
if($scope.list !== undefined)
return $scope.list();

if($scope.list_func !== undefined)
return $scope.list_func()();
};
}]
};
});

但是,当我将 listFunc 属性与返回列表的函数一起使用时,我收到此错误:

VM607 angular.js:68 Uncaught Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting! Watchers fired in the last 5 iterations: [[{"msg":"fn: regularInterceptedExpression","newVal":19,"oldVal":17},{"msg":"fn: regularInterceptedExpression","newVal":"Harry"},{"msg":"fn: regularInterceptedExpression","newVal":"65"},{"msg":"fn: regularInterceptedExpression","newVal":"Sally"},{"msg":"fn: regularInterceptedExpression","newVal":"66"},{"msg":"fn: regularInterceptedExpression","newVal":9,"oldVal":8},{"msg":"fn: regularInterceptedExpression","newVal":"val"},{"msg":"fn: regularInterceptedExpression","newVal":"1"}],[{"msg":"fn: regularInterceptedExpression","newVal":21,"oldVal":19},{"msg":"fn: regularInterceptedExpression","newVal":"Harry"},{"msg":"fn: regularInterceptedExpression","newVal":"65"},{"msg":"fn: regularInterceptedExpression","newVal":"Sally"},{"msg":"fn: regularInterceptedExpression","newVal":"66"},{"msg":"fn: regularInterceptedExpression","newVal":10,"oldVal":9},{"msg":"fn: regularInterceptedExpression","newVal":"val"},{"msg":"fn: regularInterceptedExpression","newVal":"1"}],[{"msg":"fn: regularInterceptedExpression","newVal":23,"oldVal":21},{"msg":"fn: regularInterceptedExpression","newVal":"Harry"},{"msg":"fn: regularInterceptedExpression","newVal":"65"},{"msg":"fn: regularInterceptedExpression","newVal":"Sally"},{"msg":"fn: regularInterceptedExpression","newVal":"66"},{"msg":"fn: regularInterceptedExpression","newVal":11,"oldVal":10},{"msg":"fn: regularInterceptedExpression","newVal":"val"},{"msg":"fn: regularInterceptedExpression","newVal":"1"}],[{"msg":"fn: regularInterceptedExpression","newVal":25,"oldVal":23},{"msg":"fn: regularInterceptedExpression","newVal":"Harry"},{"msg":"fn: regularInterceptedExpression","newVal":"65"},{"msg":"fn: regularInterceptedExpression","newVal":"Sally"},{"msg":"fn: regularInterceptedExpression","newVal":"66"},{"msg":"fn: regularInterceptedExpression","newVal":12,"oldVal":11},{"msg":"fn: regularInterceptedExpression","newVal":"val"},{"msg":"fn: regularInterceptedExpression","newVal":"1"}],[{"msg":"fn: regularInterceptedExpression","newVal":27,"oldVal":25},{"msg":"fn: regularInterceptedExpression","newVal":"Harry"},{"msg":"fn: regularInterceptedExpression","newVal":"65"},{"msg":"fn: regularInterceptedExpression","newVal":"Sally"},{"msg":"fn: regularInterceptedExpression","newVal":"66"},{"msg":"fn: regularInterceptedExpression","newVal":13,"oldVal":12},{"msg":"fn: regularInterceptedExpression","newVal":"val"},{"msg":"fn: regularInterceptedExpression","newVal":"1"}]] http://errors.angularjs.org/1.6.2/$rootScope/infdig?p0=10&p1=%5B%5B%7B%22ms…2fn%3A%20regularInterceptedExpression%22%2C%22newVal%22%3A%221%22%7D%5D%5D at VM607 angular.js:68 at Scope.$digest (VM607 angular.js:17893) at Scope.$apply (VM607 angular.js:18125) at done (VM607 angular.js:12233) at completeRequest (VM607 angular.js:12459) at XMLHttpRequest.requestLoaded (VM607 angular.js:12387)

我创建了this plunker示例(打开 JavaScript 控制台,您可以看到这些错误)演示我需要什么。在此示例中,我收到这些错误,但 View 仍然会更新。在我正在开发的应用程序(更大)上,我收到了很多 $digest 错误,导致网站速度变慢并且 View 无法更新。

绑定(bind)函数而不以无限循环结束的最佳方法是什么?

最佳答案

Angular 注册了一个隐式 $watchCollection关于get_list()表达。该表达式将至少被调用两次,因为 Angular 想要检查模型是否已稳定。

<ul>
<li ng-repeat="obj in get_list()">
name: {{ obj.name }}<br />
age: {{ obj.age }}
</li>
</ul>

您的代码每次都会返回不同的对象数组get_list()被调用,所以 Angular 会继续消化,直到达到最大消化周期限制。

  $scope.get_list = function(val) {
return function() {
return [ { name: "val", age: val } ];
}
}

尽管内容相同,但该函数每次调用时都会创建新对象。

避免在模板中使用函数调用。相反,将值放在范围内,并让指令对这些值的变化使用react。

来自文档:

Error: $rootScope:infdig

This error occurs when the application's model becomes unstable and each $digest cycle triggers a state change and subsequent $digest cycle. AngularJS detects this situation and prevents an infinite loop from causing the browser to become unresponsive.

One common mistake is binding to a function which generates a new array every time it is called. For example:

<div ng-repeat="user in getUsers()">{{ user.name }}</div>
$scope.getUsers = function() {
return [ { name: 'Hank' }, { name: 'Francisco' } ];
};

Since getUsers() returns a new array, AngularJS determines that the model is different on each $digest cycle, resulting in the error. The solution is to return the same array object if the elements have not changed:

var users = [ { name: 'Hank' }, { name: 'Francisco' } ];

$scope.getUsers = function() {
return users;
};

— AngularJS Error Reference - Error: $rootScope:infdig


Should I give up with this kind of functions and use a filter instead?

TL;DR 是的。

组件应该只充当“皮肤”。他们应该只显示给他们的数据并将用户事件传达给父 Controller 。型号应该是Single Source of Truth 。指令不需要从父 Controller 获取数据。

表达式&绑定(bind)只能用于将用户事件传递给父 Controller 。然后父 Controller 应该适本地改变模型。这个Separation of Concerns使应用程序更容易理解、调试、测试和维护。


One more question: this also applies for functions returning functions, right?

应该避免“函数返回函数”模式。它造成了一个令人困惑的模板。相反,使用局部变量调用函数:

<my-component on-event="gotEvent($event)">
</my-compnent>
scope: { onEvent: "&" },
template: `<input ng-model=myModel ng-change="myChange()" />`,
link: function(scope, elem, attrs) {
scope.myChange = function() {
scope.onEvent({$event: myModel});
};
}

我建议在局部变量前加上 $ 前缀以将它们与父作用域变量区分开来。有些人建议使用 $event符合 Angular 2+ 的约定。

来自文档:

  • & or &attr - provides a way to execute an expression in the context of the parent scope. If no attr name is specified then the attribute name is assumed to be the same as the local name. Given <my-component my-attr="count = count + $value"> and the isolate scope definition scope: { localFn:'&myAttr' }, the isolate scope property localFn will point to a function wrapper for the count = count + $value expression. Often it's desirable to pass data from the isolated scope via an expression to the parent scope. This can be done by passing a map of local variable names and values into the expression wrapper fn. For example, if the expression is increment($amount) then we can specify the amount value by calling the localFn as localFn({$amount: 22}).

— AngularJS Comprehensive Directive API Reference ($scope)

关于angularjs - 与函数的指令绑定(bind)最终出现在 $digest 循环中 - 错误 : $rootScope:infdig,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44975005/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com