角垫自动完成在 FormArray 中不起作用? [英] Angular mat autocomplete does not working in FormArray?

查看:30
本文介绍了角垫自动完成在 FormArray 中不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 FormArray 中实现 mat 自动完成.我点击了这个链接,但是当我尝试打开链接时,我的控制台有很多错误,就像下面的例子一样:

编辑

在你的建议@polyglot 之后,一些错误消失了,只是这个数组的异步管道和 ngFor 有问题,如下图所示,并且 this.filteredEmployees[index] 有错误 manageNameControl.

输入'Observable>'不可分配给类型Observable".输入'Observable'缺少类型IEmployee"中的以下属性:id、firstName、

解决方案

RESOLVED

我已经解决了已过滤的员工需要

filteredEmployees: IEmployee[] 和 manageNameControl 方法看起来像

manageNameControl(index: number) {var arrayControl = this.createProjectForm.get('projectTeamMembers') as FormArray;arrayControl.at(index).get('employeeId').valueChanges.管道(去抖动时间(300),switchMap((value) => this.projectManagementService.filterEmployees(value)),).subscribe((员工:IEmployee[]) => (this.filteredEmployees =员工));}

并使用 from html 表单删除 aync 管道

 <input matInput formControlName='employeeId' name='employeeId' placeholder="开始输入员工的名字或姓氏.";[matAutocomplete]=自动"><mat-error *ngIf=t.get('employeeId').errors?.required">{{ 'FIELD_REQUIRED_MESSAGE' |翻译 }}</mat-error></mat-form-field><mat-autocomplete #auto="matAutocomplete";[displayWith]=employeeTypeaheadDisplayFn(filteredEmployees)"><mat-option *ngFor=让过滤员工的员工"[值]=employee.id">{{employee.firstName}} {{employee.lastName}}</mat-option></mat-autocomplete>

I'm trying to implement mat autocomplete in FormArray. I followed this link but my console have a lot of errors when I try to open link when put this code like example from below:

https://stackblitz.com/edit/angular-szxkme-yfphur?file=app%2Fautocomplete-display-example.ts

create-project.ts

export class CreateProjectComponent implements OnInit {
pageNavigation: IPageNavigation = {
    pageTitle: 'Project Management',
    subPages: [{ label: 'Projects', link: '/projects' }],
};

createProjectForm: FormGroup;
projectTeamMemberFormArray = new FormArray([]);      
filteredEmployees: Observable<IEmployee[]>;

constructor(       
    private formBuilder: FormBuilder,
    private projectManagementService: ProjectManagementService       
) { }

ngOnInit(): void {       
    this.buildForm();
}

buildForm(): void {
    this.createProjectForm = this.formBuilder.group({            
        projectTeamMembers: this.projectTeamMemberFormArray
    });
}

manageNameControl(index: number) {
    var arrayControl = this.createProjectForm.get('projectTeamMembers') as FormArray;
    this.filteredEmployees[index] = arrayControl.at(index).get('firstName').valueChanges
        .pipe(
            startWith<string | IEmployee>(''),
            map(value => typeof value === 'string' ? value : value.firstName),
            map(name => name ? this.projectManagementService.filterEmployees(name) : null)
        );
}

addProjectTeamMember(teamMember?: IProjectMember): void {
    this.projectTeamMemberFormArray = this.createProjectForm.get('projectTeamMembers') as FormArray;
    this.projectTeamMemberFormArray.push(this.createProjectTeamMemberItem(teamMember));

    this.manageNameControl(this.projectTeamMemberFormArray.length - 1);
}

createProjectTeamMemberItem(teamMember?: IProjectMember): FormGroup {
    return this.formBuilder.group({
        employeeId: new FormControl((teamMember && teamMember.employeeId) || null, Validators.required),
        firstName: new FormControl((teamMember && teamMember.firstName) || null, Validators.required),
        memberRoles: new FormControl((teamMember && teamMember.projectRoles) || null, Validators.required),
    });
}

removeProjectTeamMemberItem(index: number, item: IProjectMember) {
    this.projectTeamMemberFormArray = this.createProjectForm.get('projectTeamMembers') as FormArray;
    this.projectTeamMemberFormArray.removeAt(index);
    this.projectTeamMembers.forEach((c: IProjectMember) => {
        if (c.id === item.id) c.deleted = true;
    });
  }
selectEmployee(employee: IEmployee): void {
    this.createProjectForm.get('employeeId').setValue(employee.id);
}

employeeTypeaheadDisplayFn(employee: IEmployee): string {
    if (employee) {
        return `${employee.lastName} ${employee.firstName}`;
    }
    return '';
}
}

create-project.html

  <form #f="ngForm" (ngSubmit)="submit()" novalidate  [formGroup]="createProjectForm">
    <section>
        <div formArrayName="projectTeamMembers" class="single-item-container"
            *ngFor="let t of createProjectForm.get('projectTeamMembers').controls; let j = index">
            <ng-container [formGroupName]="j">
            <div class="spinner" *ngIf="showLoader">
                <mat-progress-spinner [color]="'primary'" diameter="100" mode="indeterminate" value="50">
                </mat-progress-spinner>
            </div>
            <div [formGroupName]="j" *ngIf="!showLoader" fxLayout="row" fxLayoutGap="2%">
                <!-- employee -->
                <mat-form-field fxFlex="100%">
                    <input matInput formControlName='firstName' placeholder="Start typing employee first or last name."
                        [matAutocomplete]="auto">
                    <mat-error *ngIf="t.get('firstName').errors?.required">
                        {{ 'FIELD_REQUIRED_MESSAGE' | translate }}
                    </mat-error>
                </mat-form-field>
                <mat-autocomplete #auto="matAutocomplete" [displayWith]="employeeTypeaheadDisplayFn" (optionSelected)="selectEmployee($event.option.value.id)">
                    <mat-option *ngFor="let employee of filteredEmployees[j] | async" [value]="employee">
                        {{ employee.firstName }} {{ employee.lastName }}
                    </mat-option>
                </mat-autocomplete>
                <div class="input-bottom">
                    <button mat-raised-button color="warn" (click)="removeProjectTeamMemberItem(j, t.value)">
                        Delete
                    </button>
                </div>
            </div>
        </ng-container>
        </div>
        <div class="form-footer">
            <div class="items-buttons">
                <button mat-raised-button color="primary" type="button"
                    (click)="addProjectTeamMember()">{{'COMPONENTS.PROJECT.ADD_NEW_TEAM_MEMBER' | translate}}</button>
            </div>
        </div>
    </section>
</form>

project-management.service.ts

export interface IEmployee {
id: number;
firstName: string;
lastName: string;
}
   filterEmployees(searchTerm: string): Observable<IEmployee[]> {
    const reqUrl = `${environment.mPortalWebApi}employee-profiles/search?searchTerm=${searchTerm}`;

    return this.http.get(reqUrl).pipe(
        map((response: IEmployee[]) => response),
        catchError((error) => _throw(error)),
    );
}

I would appreciate it if someone would look at the code and see what I missed. Thanks.

EDIT

After your suggestions @polyglot some errors disappeared just there issue with async pipe and ngFor for this array like in picture below and there is error manageNameControl for this.filteredEmployees[index].

Type 'Observable<Observable<IEmployee[]>>' is not assignable to type 'Observable'. Type 'Observable<IEmployee[]>' is missing the following properties from type 'IEmployee': id, firstName,

解决方案

RESOLVED

I've fixed issue filteredEmyployee needs to be

filteredEmployees: IEmployee[] and the manageNameControl method looks like

manageNameControl(index: number) {
    var arrayControl = this.createProjectForm.get('projectTeamMembers') as FormArray;
    arrayControl.at(index).get('employeeId').valueChanges
        .pipe(
            debounceTime(300),
            switchMap((value) => this.projectManagementService.filterEmployees(value)),
        )
        .subscribe((employees: IEmployee[]) => (this.filteredEmployees = employees));
}

and removed aync pipes with from html form

  <mat-form-field fxFlex="100%">
                    <input matInput formControlName='employeeId' name='employeeId' placeholder="Start typing employee first or last name."
                        [matAutocomplete]="auto">
                    <mat-error *ngIf="t.get('employeeId').errors?.required">
                        {{ 'FIELD_REQUIRED_MESSAGE' | translate }}
                    </mat-error>
                </mat-form-field>
                <mat-autocomplete #auto="matAutocomplete"  [displayWith]="employeeTypeaheadDisplayFn(filteredEmployees)">
                    <mat-option *ngFor="let employee of filteredEmployees" [value]="employee.id">
                        {{ employee.firstName }} {{ employee.lastName }}
                    </mat-option>
                </mat-autocomplete>

这篇关于角垫自动完成在 FormArray 中不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆