下面是简化的 plunker 示例:
https://plnkr.co/edit/yU9gLsiQJkwsz81H0RBw?p=preview
有一个绑定到 val 的输入:
<input id="inpt" [(ngModel)]="val"/>
还有一些绑定到同一值的 UI:
<h1>{{val}}</h1>
如果您输入输入,h1 将发生变化。
该按钮正在扮演第三方的角色,它通过以下方式更改输入:
document.getElementById("inpt").value="33";
单击按钮后,h1 值不会更改为"33",因为模型尚未更新。
我使用的实际第三方是输入字段上的jqueryui自动完成。
如何强制数据绑定运行(特别是这里需要的是从 DOM 到模型),以便 UI 的其余部分可以对此更改做出反应?
你会在 plunker 中看到我试图使用 ngZone 将 document.getElementById("inpt").value ="33" 包装在 ngZone.run 中,但我担心这可能只与模型 -> DOM 方向有关。我看到了更多与更新 DOM 有关的示例。
在angularjs中,来自DOM的模型更新可以通过以下方式完成: angular.element(this).triggerHandler('input');
你能做到吗?默认 ngModel 侦听输入事件以执行视图>模型更新。
export function createFakeEvent(type: string) {
let event = document.createEvent('Event');
event.initEvent(type, true, true);
return event;
}
function dispatchFakeEvent(node: Node | Window, type: string) {
node.dispatchEvent(createFakeEvent(type));
}
do() {
document.getElementById("inpt").value="33";
dispatchFakeEvent( document.getElementById("inpt"), 'input');
}
您可以在do()
方法中处理此问题,如下所示
do() {
this.val = "33"
}
更新的普伦克
您的问题似乎源于使用候选版本。当前版本按预期工作。在这里,您可以看到它按预期工作。
export class AppComponent {
val = 'someThing'
do() {
document.getElementById("inpt").value="33";
}
}
只是工作。像这样的事情通常由zonejs检测到。但是,如果你的第3方做了一些非常出乎意料的事情,并且在当前版本的angular中没有更新,你可以看看changeDetectorRef。您可以使用.markForCheck
或事件.tick
方法来强制更改检测。