当第三方使用 DOM 更改输入的值时,强制 Angular2 更新模型



下面是简化的 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方法来强制更改检测。

最新更新