【发布时间】:2020-06-05 03:48:05
【问题描述】:
我正在将大型应用程序升级到启用 Ivy 编译的 Angular 9 的过程中,并且遇到了将 NgModel 注入自定义指令的行为似乎发生了变化
使用该指令时,在使用 IVY 编译时,版本 7 和版本 8/9 注入的 NgModel 是不同的。
禁用 Ivy 编译时不会发生这种情况。
指令 (tabSelect)
import { Directive, AfterViewInit, OnDestroy, Optional } from '@angular/core';
import { NgModel } from "@angular/forms";
import { MatAutocompleteTrigger } from '@angular/material/autocomplete';
@Directive({
selector: '[tabSelect]',
providers: [NgModel]
})
export class TabSelectDirective implements AfterViewInit, OnDestroy {
observable: any;
onChange: any;
constructor(@Optional()
private autoTrigger: MatAutocompleteTrigger,
private ngModel: NgModel) { }
ngAfterViewInit() {
this.observable = this.autoTrigger.panelClosingActions.subscribe(x => {
if (this.autoTrigger.activeOption && this.autoTrigger.activeOption.value) {
if (this.ngModel.model !== this.autoTrigger.activeOption.value) {
this.ngModel.update.emit(this.autoTrigger.activeOption.value);
this.autoTrigger.autocomplete.optionSelected.emit();
}
} else {
console.log(this.ngModel);
console.log(this.autoTrigger);
if (!this.ngModel.viewModel || this.ngModel.viewModel === "")
this.ngModel.update.emit(null);
};
});
}
ngOnDestroy() {
this.observable.unsubscribe();
}
};
在 HTML 中使用指令
<mat-form-field appearance="outline" color="primary" class="mat-input-no-validation pull-right"
style="width: 130px; margin-left: 10px">
<mat-label>Document Group</mat-label>
<input matInput
placeholder="Search.."
name="documentGroupInput"
spellcheck="false"
[(ngModel)]="documentNode.documentGroup"
[matAutocomplete]="documentGroupAuto"
#documentGroupCtrl="ngModel"
tabSelect />
<div class="small-progress-spinner-container" [hidden]="!documentGroupSearching">
<mat-progress-spinner [diameter]="15" [mode]="'indeterminate'"></mat-progress-spinner>
</div>
<mat-autocomplete #documentGroupAuto="matAutocomplete">
<mat-option *ngFor="let documentGroup of documentGroupResults; trackBy:formatters.trackIndex" [value]="documentGroup">
<div class="autocomplete-option">
{{ documentGroup }}
</div>
</mat-option>
</mat-autocomplete>
</mat-form-field>
在检查注入指令的 NgModel 时,在 Angular 7 中,我们会看到 Control 名称
NgModel {_parent: NgForm, name: "documentGroupInput", valueAccessor: MatAutocompleteTrigger, _rawValidators: Array(0), _rawAsyncValidators: Array(0), …}
而在 Angular 9 中我们不这样做
NgModel {_parent: NgForm, name: null, valueAccessor: MatAutocompleteTrigger, _rawValidators: Array(0), _rawAsyncValidators: Array(0), …}
这让我相信注入的 NgModel 实际上并不是 Ivy 中控件本身的模型,而这得到了赋值和发出更改事件不再起作用的方法的支持
任何想法发生了什么变化以及我如何解决这个问题?
谢谢
编辑:- 修正代码
import { Directive, AfterViewInit, OnDestroy, Optional } from '@angular/core';
import { NgModel } from "@angular/forms";
import { MatAutocompleteTrigger } from '@angular/material/autocomplete';
@Directive({
selector: '[tabSelect][ngModel]',
providers: []
})
export class TabSelectDirective implements AfterViewInit, OnDestroy {
observable: any;
onChange: any;
constructor(@Optional()
private autoTrigger: MatAutocompleteTrigger,
private ngModel: NgModel) { }
ngAfterViewInit() {
console.log(this.ngModel);
this.observable = this.autoTrigger.panelClosingActions.subscribe(x => {
if (this.autoTrigger.activeOption && this.autoTrigger.activeOption.value) {
if (this.ngModel.model !== this.autoTrigger.activeOption.value) {
this.ngModel.update.emit(this.autoTrigger.activeOption.value);
this.autoTrigger.autocomplete.optionSelected.emit();
}
} else {
console.log(this.ngModel);
console.log(this.autoTrigger);
if (!this.ngModel.viewModel || this.ngModel.viewModel === "")
this.ngModel.update.emit(null);
};
});
}
ngOnDestroy() {
this.observable.unsubscribe();
}
};
【问题讨论】:
-
我正在我的开发笔记本电脑上积极调试这个完全相同的问题,并试图找出解决方案。
this.ngModel.update.emit确实不再更新期望值。我很高兴我不是唯一一个......
标签: angular angular-directive ivy angular-ngmodel