Javascript 角度6:从选择下拉事件触发的表达式ChangedTerithasBeenCheckedError

Javascript 角度6:从选择下拉事件触发的表达式ChangedTerithasBeenCheckedError,javascript,angular,typescript,angular-bootstrap,Javascript,Angular,Typescript,Angular Bootstrap,哪些代码更改可以纠正下面描述的错误? 用例 下拉式输入UI可通过模式防止意外的选定值更改。但是,连接到下拉列表的事件(单击、焦点或其他)会导致在开发模式下的Chrome控制台中观察到的表达式ChangedTerithasBeenCheckedError 观察结果 单击下拉列表时,将抛出一个表达式ChangedTerithasBeenCheckedError(请参阅控制台) 预期结果 单击下拉列表时,将打开一个模式,不会出现错误 演示 中的演示链接 注释 正如“关于ExpressionChang

哪些代码更改可以纠正下面描述的错误?

用例

下拉式输入UI可通过模式防止意外的选定值更改。但是,连接到下拉列表的事件(单击、焦点或其他)会导致在开发模式下的Chrome控制台中观察到的表达式ChangedTerithasBeenCheckedError

观察结果

单击下拉列表时,将抛出一个表达式ChangedTerithasBeenCheckedError(请参阅控制台)

预期结果

单击下拉列表时,将打开一个模式,不会出现错误

演示

中的演示链接

注释

  • 正如“关于ExpressionChangedTerithasBeenCheckedError您需要知道的一切”中所述,我尝试触发更改 检测(参见应用组件ts:48-49中的注释,标记为 步骤1和步骤2),但未成功(可能触发位置不正确?)
  • 演示中的模式对于[OK]和[CANCEL]没有完全实现,因为它不会影响错误
  • 该代码是大型应用程序的简化版本
哪些代码更改可以纠正下面描述的错误?

这样的代码应该可以帮助您:

<select 
  [(ngModel)]="building.venueId"
  #ngModel="ngModel"
  ^^^^^^^^^^^^^^^^^^
  get hold of NgModel instance
  ...
  (click)="ngModel.control.markAsTouched(); confirmChangeItem(building.venueId)">
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
           and prepare FormControl to the changes

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
并为更改准备FormControl

更新


我忘了说在这种情况下可以删除
cdRef.detectChanges
和microtask,所以我很高兴知道您自己猜到了它

关于
select
元素,我看到了两件您可能想要更改的事情。(1) 您使用
ngModel
[所选]
,仅使用
ngModel
。(2) 与处理下拉列表中的
(单击)
事件不同,我建议使用
[ngModel]
的单向绑定并处理
(ngModelChange)=“processValueChange($event)”
,在确认更改之前可以进行一些检查基于@yurzuiThank的宝贵输入,删除了未使用的更改检测和微/宏任务代码!我挣扎了几个小时才找到答案!我很想知道为什么这是必要的。我的代码不更新表单,只打开一个模式,除非我使用markAsTouched工作区,否则会发生此错误。