当项目具有 BrowserAnimationsModule 时,Angular UI 未拾取数据模型更改

问题描述 投票:0回答:2

我的项目有一个选择程序的页面。在我将 BrowserAnimationsModule 添加到我的项目中之前,它工作得很好。

页面有一个“切换到A程序”按钮。无论您点击此按钮多少次,它始终都能正常工作。

请参阅正确的程序选择器

但是在将BrowserAnimationsModule添加到该项目中后,第二次单击时它将设置为“空程序”。但数据模型已经设置为正确的程序,我打印在页面上。

请参阅损坏的程序选择器

该页面本身没有使用BrowserAnimationsModule。两个链接上的代码完全相同,只是损坏的链接在项目中具有 BrowserAnimationsModule。

我尝试了 Firefox 和 Edge,都有同样的问题。

我也尝试了 Angular 版本 12 和 15,都有同样的问题。

当前的实现是使用 FormControl。我也尝试了 [(ngModel)] 并遇到了同样的问题。

两个链接都有源码图,可以在源码上调试。 请使用浏览器控制台查看它们。

我看到有人提到了 BrowserAnimationsModule 上的 a bug。但似乎已经修复了。

您可以完全控制这个小项目在 stackblitz

angular animation data-binding module
2个回答
0
投票

您可以将changeDetection:ChangeDetectionStrategy.OnPush添加到ProgramSelectorByClientComponent来看看会发生什么。

这可能无法解决问题,但这是调试问题的良好开端。


0
投票

TLDR;当数组被替换时执行
this.cd.detectChanges()
(这里是stackblitz)。


每次调用以下行时,您的代码都会销毁并重新创建

select
内的整个选项,这意味着保存在
FormControl
处的
selectedProgram
中设置的任何先前值都会丢失:

// line inside `loadPrograms()` method
this.allProgramList = res;

我看到您尝试通过每次重置选项时调用

followProgram()
方法来解决此问题,这可能没问题。但当涉及动画时,它可能会导致问题,这种错误(通过在某些点调用
detectChanges()
解决的那种错误)通常与代码需要更新时 DOM 没有及时更新有关。

我的猜测是,通过添加模块,它可以通过稍微延迟

select
数组的创建来“增强”
option
的行为。当您尝试设置新值时,没有给予足够的时间来完全创建它。所以,我能想到三种解决方案......

所有这些都经过了区域测试并且可以工作,请在 stackblitz 示例中查看它们

1.更换阵列后立即致电
this.cd.detectChanges()

这将强制您的选择在后续步骤中被访问时完全呈现:

// line inside `loadPrograms()` method
this.allProgramList = res;
this.cd.detectChanges()

2.致电
setTimeout(() => {...}, 1)

这将为在单独的生命周期更改检测运行中处理延迟提供“时间”(这是一个深入的主题),

// line inside `loadPrograms()` method
setTimeout(() => {
    this.followProgram();
},1)

3.不要替换整个数组,只需推送新值

这将使 Angular 不会破坏你的 dom,这样就不需要等待另一个生命周期来设置值:

// line inside `loadPrograms()` method
res.forEach((item) => {
    if (!this.allProgramList.find((p) => p.pId === item.pId)) {
        this.allProgramList.push(item);
    }
});

我对这件事的最后评论是鼓励您将其报告为错误,仅添加额外的模块不应以这种方式改变行为。

© www.soinside.com 2019 - 2024. All rights reserved.