在指令中调用$setViewValue并不会触发控制器中的$watch
Calling $setViewValue in a directive doesn't fire $watch in the controller
我正在使用一个指令与ngModelController像这样
var directive = {
link: link,
restrict: 'E',
require: '?ngModel'
}
我的链接函数是这样做的(我省略了长指令的东西)
function link(scope, element, attrs, ctrl) {
scope.updateModel = function(){
var newModel = {};
newModel.aValue = 'foo';
ctrl.$setViewValue(newModel);
}
}
我在控制器
中使用指令View:这是正确更新的
<my-directive ng-model="aModel">
{{aModel.aValue}} // This is changed correctly when I update the value in the directive
</my-directive>
控制器:这里是我有问题的地方
$scope.aModel = {};
$scope.aModel.aValue = 'bar';
$scope.$watch('aModel', function(newValue, oldValue){
console.log('aModel changed'); // This is never fired
});
$scope.$watch('aModel.aValue', function(newValue, oldValue){
console.log('aModel changed'); // This is neither fired
});
$setViewValue
的文档说
"注意,调用这个函数不会触发$digest。"
所以我尝试用$render
, $digest
或$apply
手动启动它,但每次都遇到麻烦,因为控制台说$digest is already in progress
.
那么问题是什么呢?
我刚意识到一件很有趣的事。
添加$timeout
来检查控制器中的值,我意识到它实际上并没有改变,这可能就是没有调用$watch函数的原因。
但由于视图是更新的,我不太明白。
情况如下:
控制器$timeout(function(){
console.log('Check aModel value in the controller');
console.log($scope.aModel.aValue); // This is always 'bar' even if the view display 'foo'
},10000);
更新2
我想我发现了问题:ngModel不能是一个对象,但它必须是一个值。
我留下这个问题,看看是否有人提出不同的解决方案,但我想这就是问题的关键。
更新3
我错了,你可以把ngModel更新为对象,但是没有办法触发$watch方法。
我创建了一个活塞来显示问题。
我设置了一个较大的超时以避免任何$digest正在进行的问题。
如有任何提示,我将不胜感激。
为$watch
函数添加第三个参数true
使用不带时间参数的$timeout来调用$apply并触发摘要循环。这将导致它延迟几分之一秒执行,并且不会在摘要循环错误中运行到摘要循环中。显然,你所做的不是"angular感知",所以你需要使用$apply来触发摘要循环,但是你在一个摘要循环中,所以你需要使用上面提到的"hack"。
相关文章:
- 在指令控制器中使用$attrs时出现问题
- 有没有任何方法可以将控制器从文件加载到ui路由器$stateProvider中
- 从控制器返回后Ajax启动事件激发
- 在控制器上使用“$watch”时,为什么不更新此隐藏字段
- 使用不带$scope的$watch(作为语法的控制器)
- [自定义指令]将范围.$watch放在链接上与将范围.$watch放在控制器上的区别
- angularJS$watch在使用控制器更新数据时不在指令中工作
- 控制器中的$watch在将项推入指令中的数组时未启动
- 保持“$watch”功能远离控制器的最佳实践
- 使用`this$watch`而不是'scope$手表`with'控制器组件'
- Angular:控制器和指令之间的共享数据.$watch是如何工作的
- 在指令中调用$setViewValue并不会触发控制器中的$watch
- $watch不能在其他控制器的变量上工作
- 使用美元的范围.$watch在控制器中使用' this '作用域时
- 所选的Angular指令不会为控制器As触发$watch
- 美元的范围.父控制器上的$watch不会触发子控制器上的ng-select
- Angularjs: $watch不能在ngTable的控制器中工作
- 使用controllerAs语法通过$watch指令更改父控制器模型
- angularjs控制器中的Initialization和$watch
- 带控制器的指令内部的Angular watch