为啥在下拉列表中加载组件时不会触发 ngmodelChange 事件?
Posted
技术标签:
【中文标题】为啥在下拉列表中加载组件时不会触发 ngmodelChange 事件?【英文标题】:Why does ngmodelChange event not fire when component loads on a dropdown?为什么在下拉列表中加载组件时不会触发 ngmodelChange 事件? 【发布时间】:2021-02-23 00:39:51 【问题描述】:在我的 Angular 8 组件中,我向下拉控件添加了双向绑定。
观点
<select (ngModelChange)='termSelectChanged($event)' [ngModel]="selected">
<option [ngValue]="t" *ngFor='let t of termsColl'>t?.code</option>
</select>
组件代码
export class AppComponent implements OnInit
public termsColl : Array<DDModel>;
public selected : DDModel;
constructor( private s : DDService )
termSelectChanged( event )
alert('HIT');
ngOnInit()
//service call #1
this.s.getDataForComplexBind().subscribe( data =>
this.termsColl = data;
, error => error );
//service call #2
this.s.getOtherData( ).subscribe( data =>
//model changes here
this.selected = this.termsColl[1];
, error => console.error(error); );
当组件加载时,它会执行 ngOnInit() 并将模型绑定属性 Selected
设置为数组的第一个元素 termsColl
。 termsColl
有数据,但 this.selected = this.termsColl[1];
行不会将所选选项更改为下拉列表中的第一个元素。事实上,当组件加载时,我期待它触发事件ngModelChange
,但它也没有触发事件。我在代码中添加了一个alert()
,但它没有显示组件加载的时间。只有当我从下拉列表中选择一个选项时它才会显示。如何更改代码以便在组件加载时执行ngModelChange
事件?
这是我的堆栈闪电战 https://stackblitz.com/edit/angular-version-yeg27j?file=src%2Fapp%2Fapp.component.ts
【问题讨论】:
它可以帮助你参考:***.com/questions/33700266/… @ArunkumarRamasamy 我用 stakcblitz 更新了我的帖子 我不明白为什么在初始设置值时需要(ngModelChange)
触发。你能解释一下为什么吗?
【参考方案1】:
我将ngModeChange
输入更改为DDModel
,并从订阅内部调用了您的termSelectChanged()
。我也把[ngModel]
改成了[(ngModel)]
<select (ngModelChange)='termSelectChanged($event)' [(ngModel)]="selected">
<option [ngValue]="t" *ngFor='let t of termsColl'>t?.code</option>
</select>
termSelectChanged(selection: DDModel)
console.log("HIT", selection);
ngOnInit()
this.s.getOtherData().subscribe(
data =>
this.termsColl = data;
this.selected = this.termsColl[0];
this.termSelectChanged(this.selected);
,
error =>
console.error(error);
);
我无法告诉你为什么从代码更改this.selected
不会触发ngModelChange
。可能是因为在模板中调用了ngModelChange
。
【讨论】:
您的代码可以工作,但是有一个问题,当我从下拉列表中选择一个选项时,termSelectChanged() 中的“选择”对象将显示之前选择的值? 我认为由于这个声明(ngModelChange)='termSelectChanged(selected)'
只需将selected
更改为$event
或其他东西。它应该在我的猜测中起作用【参考方案2】:
您可以使用viewToModelUpdate()
的ngModel
来更新值,如果您想触发ngModelChange
。你可以在here找到更多相关信息。
但您需要进行以下更改。
在html模板中:
<select (ngModelChange)='termSelectChanged($event)' [ngModel]="selected" #ngModel="ngModel">
<option [value]="t" *ngFor='let t of termsColl'>t?.code</option>
</select>
您可以看到我在模板中添加了对 ngModel 的引用,我将在组件类中使用它。
在组件类中:
export class AppComponent
name = "Angular 6";
version = VERSION.full;
public termsColl: Array<DDModel>;
public selected: string;
@ViewChild("ngModel") ngModel: NgModel;
constructor(private s: DDService)
termSelectChanged(event)
this.selected = event;
ngOnInit()
this.s.getOtherData().subscribe(
data =>
this.termsColl = data;
this.ngModel.viewToModelUpdate(this.termsColl[1]);
,
error =>
console.error(error);
);
您可以看到我使用ngModel
引用来调用带有值的viewToModelUpdate
,这反过来会触发ngModelChange
。
由于您没有直接使用双向绑定,因此您必须将值设置为触发函数termSelectChanged
内的selected
变量。
希望这能帮助您实现您的要求。
【讨论】:
你不应该直接调用内部 NgModel 方法。 @Rishanthakumar 在您提到的帖子中,我没有使用“直接模型绑定”。我很好奇,如果我想使用“直接模型绑定”,那么如何在组件加载时触发 (ngModelChange) 事件?您能否将直接模型绑定连同现有的属性绑定一起发布? @eutychostfar 我提到的是关于“双向绑定”的内容,我们可以在其中输入[(ngModel)]="selected"
。这样您就不需要在ngModelChange
触发时更新this.selected
变量,因为它是双向绑定的。您最初触发ngModelChange
的任何理由,因为您可以通过简单的方式从更新变量的同一位置触发该方法。
@eutychostfar 我认为由于他的解决方案(ngModelChange)='termSelectChanged(selected)'
中的这一陈述,只需将selected
更改为$event
或其他东西。它应该在我的猜测中起作用。
@eutychostfar 我认为您应该将“未分配的头脑”答案标记为正确,因为它很简单。可能是我的答案可以留在这里只是为了知识。再次使其直接双向绑定,您需要放置此[(ngModel)]="selected"
,除此之外,除了此this.ngModel.viewToModelUpdate(this.termsColl[1]);
之外,您还需要为订阅中的变量分配值。然后你可以删除ngModelChange
触发器中的变量赋值。【参考方案3】:
您可以在选项元素中使用value
而不是ngValue
。并将t.code
而不是t
分配给value
属性。
<select (ngModelChange)='termSelectChanged($event)' [ngModel]="selected">
<option [value]="t.code" *ngFor='let t of termsColl'>t?.code</option>
</select>
参考:https://angular-version-xkjuff.stackblitz.io
【讨论】:
【参考方案4】:termsColl 有数据,但代码行 this.selected = this.termsColl[1];不会将所选选项更改为下拉列表中的第一个元素。
因为您使用的是属性绑定 [ngModel]="selected",而不是双向数据绑定。
[(ngModel)]="selected" 用于双向绑定,语法是compound from:
[ngModel]="selected" 和 (ngModelChange)="selected = $event"
此外,selected 的值应该是下拉菜单中可用的值,即
ngOnInit()
this.selected = this.termsColl[1].code
下面的代码对你有用:
<select [(ngModel)]="selected" (change)="onSelection()">
<option *ngFor='let t of termsColl' [value]="t.code" [selected]="selected === t.code">t?.code</option>
</select>
您可能还想参考这个https://***.com/a/63192748/13596406
【讨论】:
以上是关于为啥在下拉列表中加载组件时不会触发 ngmodelChange 事件?的主要内容,如果未能解决你的问题,请参考以下文章
AG Grid:通过 ComponentFactoryResolver 在组件中加载网格时未触发 gridReady 事件