【发布时间】:2020-03-12 10:38:12
【问题描述】:
在我们的 Angular 应用程序中,我们使用 Telerik 的控件,例如:
<kendo-recurrence-editor [start]="startDate" (valueChange)="onRecurrenceChange($event)">
</kendo-recurrence-editor>
不幸的是they don't expose a lot of properties/events,所以无法使用正常的模型绑定。这就是为什么我们只能使用valueChange 事件。
如果有人更改此控件的输入值,则正确调用onRecurrenceChange 函数:
public onRecurrenceChange(e) {
this.recurrence = e;
...
}
现在,我们要做的下一件事是验证此控件中的输入元素。
例如,如果输入的值无效,我们会重置输入的值,如下所示:
public onRecurrenceChange(e) {
...
var inputs = this.recurrenceEditorDiv.nativeElement.querySelectorAll("input");
inputs[3].value = 1;
}
该值已正确重置,因此在功能上它似乎可以工作,但同时我们得到一个 javascript 错误:ExpressionChangedAfterItHasBeenCheckedError。
似乎根本原因是我们通过在事件处理程序中自己操作 DOM 来设置此输入值。
我尝试在setTimeout() 中执行此操作,但这并不能解决问题。
所以我的问题是:我们可以通过哪种方式从 TypeScript 操作 DOM 并更改输入元素的值,并让 TypeScript 满意?
编辑:我创建了一个堆栈闪电战,但在这里我没有看到 Visual Studio 中引发的异常:https://stackblitz.com/edit/angular-x1wpld。如果你去 DAILY,并在“出现 x 次后”中输入 999,它会重置为 1。但如前所述,在 Visual Studio 中我收到ExpressionChangedAfterItHasBeenCheckedError 错误。
编辑 2:似乎可以通过将完整验证放入 setTimeout 来解决,而不是仅在 setTimeout 中设置值。
【问题讨论】:
-
你能创建a stackblitz example吗?
-
您应该阅读角度变化检测以及组件的工作原理。基本上,您不想操作 DOM 元素,除非是非常特殊的情况。我不熟悉 Kendo 库,但我很确定他们公开了自己的 ngModel 或类似属性,以便在其组件上进行双向绑定。使用它,更改将在 NgZone 中运行,即与应用程序生命挂钩管理。
-
@StepUp 我添加了它,请参阅编辑。
-
@TotallyNewb 不幸的是,他们似乎没有为此公开它:telerik.com/kendo-angular-ui/components/scheduler/api/…
标签: angular typescript dom