【问题标题】:Angular 5 Material autocomplete has null initial valueAngular 5 Material自动完成具有空初始值
【发布时间】:2018-01-21 08:37:40
【问题描述】:

我有一个自动完成表单字段,当它是一个简单的自动完成时,它可以正常工作。但是,当我尝试添加自定义过滤器时,它会失败。

自动完成的数据来自父组件。父组件有:

alldwgrevdata: Observable<DrawingRevisionIDsOnly[]>;
...
ngOnInit() {
    this.alldwgrevdata = this.drawingRevisionService.getAllDrawingRevisions();
}

并通过以下方式将数据传递给模板中的孩子:

<child [alldwgrevdata]="alldwgrevdata | async"></child>

服务返回Observable&lt;DrawingRevisionIDsOnly[]&gt;

孩子是这样设置的:

export class DrawingSelectorComponent implements OnInit {
    @Input("drawingrevs")
    drawingrevs: DrawingRevision[] = [];

    @Input("alldwgrevdata")
    alldwgrevdata: DrawingRevisionIDsOnly[] = [];

    filteredrevdata: Observable<DrawingRevisionIDsOnly[]>;

    @Input()
    public parentForm: FormGroup;

    @Output()
    onDwgChange = new EventEmitter();

    constructor(private fb: FormBuilder, private drawingRevisionService: DrawingRevisionService, private messagesService: MessagesService) { }

    ngOnInit() {
        console.log(this.alldwgrevdata);
        let dwgSelectControl = new FormControl(this.drawingrevs);
        this.parentForm.addControl('attachedDwgsControl', dwgSelectControl);

        this.filteredrevdata = dwgSelectControl.valueChanges
            .startWith([])
            .map(dwgrev => dwgrev && typeof dwgrev === 'object' ? (dwgrev.drawingID+" "+dwgrev.revisionid) : dwgrev)
            .map(dwgIDrevID => dwgIDrevID ? this.filter(dwgIDrevID) : this.alldwgrevdata.slice());
    }

    filter(dwgIDrevID: string): DrawingRevisionIDsOnly[] {
        return this.alldwgrevdata.filter(option => (option.drawingID+" "+option.revisionid).toLowerCase().indexOf(dwgIDrevID.toLowerCase()) === 0);
    }

    displayFn(dwgRev: DrawingRevisionIDsOnly): string {
        return dwgRev ? (dwgRev.drawingID+" "+dwgRev.revisionid) : "";
    }
}

错误是this.alldwgrevdata is null。在 ngOnInit() 方法中,console.log 确实输出了null,所以这个错误在某种程度上是有道理的。设置表单控件的valueChanges部分时出现问题。

我试图改变

this.alldwgrevdata.slice()

(this.alldwgrevdata==null ? [] : this.alldwgrevdata.slice())

但这没有任何效果。

如何将 Observable 的初始值设置为空数组,或者强制 valueChanges 等到数据服务完成后再进行评估?还是有一种完全不同的方法可以解决我想念的这个问题?谢谢!

【问题讨论】:

    标签: angular autocomplete rxjs angular-material2 rxjs5


    【解决方案1】:

    在这条线上

    .map(dwgIDrevID => dwgIDrevID ? this.filter(dwgIDrevID) : this.alldwgrevdata.slice());
    

    可以任意分支。如果分支到this.filter()(也使用this.alldwgrevdata),您将收到相同的错误消息。

    问题是,在这一行

    <child [alldwgrevdata]="alldwgrevdata | async"></child>
    

    传入的值最初会为null,这里使用的默认空数组

    @Input("alldwgrevdata")
    alldwgrevdata: DrawingRevisionIDsOnly[] = [];
    

    将被该 null 覆盖。 (只有在没有传入参数时才会发生默认值)。

    您可以将@Input 与set/get 语法结合使用,而不是在很多地方测试null,并将默认null 值设置为[]

    private _alldwgrevdata = [];
    @Input('alldwgrevdata')
    set alldwgrevdata(value: string) {
      this._alldwgrevdata = value || [];
    }
    get alldwgrevdata() {
      return this._alldwgrevdata;
    }
    

    【讨论】:

    • 虽然我最终不需要使用这种方法,但您的回答让我想到了一些我以前没有关注的事情,最终我得到了它的工作。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-19
    • 1970-01-01
    • 1970-01-01
    • 2021-09-30
    • 2016-10-11
    • 1970-01-01
    • 2020-01-11
    相关资源
    最近更新 更多