Pab*_*blo 2 angularjs angularjs-directive
我想要一个与对象列表一起使用的指令,但我还需要接受 2 向绑定或函数绑定。
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()();
};
}]
};
});
Run Code Online (Sandbox Code Playgroud)
但是,当我将该listFunc属性与返回列表的函数一起使用时,出现此错误:
VM607 angular.js:68 未捕获错误:[$rootScope:infdig] 已达到 10 次 $digest() 迭代。中止!在最后 5 次迭代中触发观察者: [[{"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"},{" 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)在 XMLHttpRequest.requestLoaded (VM607 angular.js:12387) 处的 completeRequest (VM607 angular.js:12459)
我创建了这个 plunker示例(打开一个 javascript 控制台,您可以看到这些错误)来演示我需要的内容。在这个例子中,我得到了这些错误,但视图仍然得到更新。在我正在开发的应用程序(它要大得多)上,我收到了很多$digest错误,网站速度变慢,视图也没有更新。
绑定函数而不以无限循环结束的最佳方法是什么?
Angular在表达式上注册了一个隐式的$watchCollectionget_list()。这个表达式至少会被调用两次,因为 angular 想要检查模型是否已经稳定。
<ul>
<li ng-repeat="obj in get_list()">
name: {{ obj.name }}<br />
age: {{ obj.age }}
</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
每次get_list()调用时,您的代码都会返回不同的对象数组,因此 angular 会继续消化,直到达到最大消化周期限制。
$scope.get_list = function(val) {
return function() {
return [ { name: "val", age: val } ];
}
}
Run Code Online (Sandbox Code Playgroud)
即使内容相同,该函数每次被调用时都会创建新对象。
避免在模板中使用函数调用。而是将值放在作用域上,并让指令对这些值的变化做出反应。
从文档:
错误:$rootScope:infdig
当应用程序的模型变得不稳定并且每个
$digest周期触发状态更改和后续$digest周期时,就会发生此错误。AngularJS 检测到这种情况并防止无限循环导致浏览器无响应。一个常见的错误是绑定到每次调用都会生成一个新数组的函数。例如:
Run Code Online (Sandbox Code Playgroud)<div ng-repeat="user in getUsers()">{{ user.name }}</div>Run Code Online (Sandbox Code Playgroud)$scope.getUsers = function() { return [ { name: 'Hank' }, { name: 'Francisco' } ]; };由于
getUsers()返回一个新数组,AngularJS 确定模型在每个$digest循环中都不同,从而导致错误。如果元素没有改变,解决方案是返回相同的数组对象:Run Code Online (Sandbox Code Playgroud)var users = [ { name: 'Hank' }, { name: 'Francisco' } ]; $scope.getUsers = function() { return users; };
我应该放弃这种功能而使用过滤器吗?
TL; DR 是的。
组件应该只是充当“皮肤”。他们应该只显示提供给他们的数据并将用户事件传达给父控制器。模型应该是唯一的真相来源。指令不需要从父控制器获取数据。
表达式&绑定应该只用于将用户事件传递给父控制器。然后父控制器应该适当地更改模型。这种关注点分离使应用程序更易于理解、调试、测试和维护。
还有一个问题:这也适用于返回函数的函数,对吗?
应该避免“函数返回函数”模式。它造成了一个令人困惑的模板。而是使用本地人调用函数:
<my-component on-event="gotEvent($event)">
</my-compnent>
Run Code Online (Sandbox Code Playgroud)
scope: { onEvent: "&" },
template: `<input ng-model=myModel ng-change="myChange()" />`,
link: function(scope, elem, attrs) {
scope.myChange = function() {
scope.onEvent({$event: myModel});
};
}
Run Code Online (Sandbox Code Playgroud)
我建议在局部变量前加上前缀以$将它们与父作用域变量区分开来。有些人建议使用$event以符合 Angular 2+ 的约定。
从文档:
&或&attr- 提供一种在父作用域的上下文中执行表达式的方法。如果未指定属性名称,则假定属性名称与本地名称相同。给定<my-component my-attr="count = count + $value">和隔离范围定义scope: { localFn:'&myAttr' },隔离范围属性localFn将指向count = count + $value表达式的函数包装器。通常希望通过表达式将数据从隔离作用域传递到父作用域。这可以通过将局部变量名称和值的映射传递到表达式包装器 fn 中来完成。例如,如果表达式是increment($amount)then 我们可以通过调用localFnas来指定数量值localFn({$amount: 22})。
| 归档时间: |
|
| 查看次数: |
917 次 |
| 最近记录: |