角度过滤和绑定(ngModelChange)

时间:2020-05-13 20:38:02

标签: html angular typescript

我正在从事酒店项目。我有一个预订屏幕。在这里,我询问酒店名称,地区名称,入住和退房日期以及成人和儿童的数量。输入必要的信息后,按搜索按钮时,将根据其中的值进行过滤。我使用(NgModelChange)方法将日期过滤器与html连接,但无法正确将html与hotel和region方法连接。我做了一个过滤器作为实验,但是得到了错误的结果。我不知道我在哪里犯错。我该如何解决?

.html

<form [formGroup]="form">
<mat-form-field>
    <label>Which Hotel?</label>
    <input type="text" matInput [matAutocomplete]="name" formControlName="name" (change)="changeHotel()" />
    <mat-autocomplete #name="matAutocomplete">
        <mat-option *ngFor="let hotel of filteredHotels | async" [value]="hotel">
            {{hotel}}
        </mat-option>
    </mat-autocomplete>
</mat-form-field>
&nbsp;
<mat-form-field>
    <label>Which Region?</label>
    <input type="text" matInput [matAutocomplete]="region" formControlName="region" (change)="changeRegion()" />
    <mat-autocomplete #region="matAutocomplete">
        <mat-option *ngFor="let region of filteredRegions | async" [value]="region">
            {{region}}
        </mat-option>
    </mat-autocomplete>
</mat-form-field>
&nbsp;
<mat-form-field>
    <label>Entry Date?</label>
    <input matInput [matDatepicker]="mdpStartDate" formControlName="startDate" (ngModelChange)="changeDate()">
    <mat-datepicker-toggle matSuffix [for]="mdpStartDate"></mat-datepicker-toggle>
    <mat-datepicker #mdpStartDate></mat-datepicker>
</mat-form-field>
&nbsp;
<mat-form-field>
    <label>Pay Date?</label>
    <input matInput [matDatepicker]="mdpEndDate" formControlName="endDate" (ngModelChange)="changeDate()">
    <mat-datepicker-toggle matSuffix [for]="mdpEndDate"></mat-datepicker-toggle>
    <mat-datepicker #mdpEndDate></mat-datepicker>
</mat-form-field>
<br />
<mat-form-field>
    <label>Adult Number?</label>
    <input type="number" min="1" matInput formControlName="adult" (ngModelChange)="filterAge()">
</mat-form-field>
&nbsp;
<mat-form-field>
    <label>Chd Number?</label>
    <input type="number" min="0" max="3" value="0" matInput formControlName="chd" (ngModelChange)="filterAge()">
</mat-form-field>
&nbsp;
<button type="button" class="btn btn-success" (click)="search()">Search</button>

.ts

 form = new FormGroup({
    name: new FormControl(''),
    region: new FormControl(''),
    adult: new FormControl(1),
    chd: new FormControl(0),
    startDate: new FormControl(),
    endDate: new FormControl(),
});

filtered: any[];
showList = false;
name = '';
regions: string[];
hotels: Hotel[] = [];

filteredHotels: Observable<string[]>;
filteredRegions: Observable<string[]>;

ngOnInit() {

    this.regions = this.hotels.reduce((arr: string[], current) => {
        if (!arr.includes(current.regionName)) {
            arr.push(current.regionName);
        }
        return arr;
    }, []);


    this.filteredHotels = this.form.get("name").valueChanges
        .pipe(
            startWith(''),
            map(v => {
                return this.filterHotels(v)
            })
        );

    this.filteredRegions = this.form.get("region").valueChanges
        .pipe(
            startWith(''),
            map(value => this.filterRegions(value).map(h => h.regionName))
        );

    this.form.get("adult").valueChanges.
        subscribe(v => {
            this.adult = new Array(v).map(e => new Object)
        });

    this.form.get("chd").valueChanges
        .subscribe(v => {
            this.children = new Array(v).map(e => new Object)
        });


    this.hotelservice.getHotels().subscribe(
        data => {
            this.hotels = data;
            this.dsHotels.data = data;
            this.dsHotels.paginator = this.paginator;
        },
        err => {
            console.error("Hata oluştu: ", err);
        }
    );
}

private filterHotels(value: string): string[] {
    const name = value.toLowerCase();

    return this.hotels
        .map(x => x.hotelName)
        .filter(option => option.toLowerCase().includes(name));
}

private filterRegions(value: string): Hotel[] {
    const region = value.toLowerCase();

    return this.hotels
        .filter(hotel => hotel.regionName.toLowerCase().includes(region));
}


private isEqual(date1: Date, date2: Date) {
    return date1.getDate() == date2.getDate() && date1.getMonth() == date2.getMonth() && date1.getFullYear() == date2.getFullYear();
}


private isDataEqualToDate(value1: any, date2: Date) {
    if (value1 == null) return true;
    return this.isEqual(new Date(value1), date2);
}

private getFilteredDate(): Hotel[] {
    return this.hotels.filter(
        x => this.isDataEqualToDate(this.form.get("startDate").value, new Date(x.checkInDate))
            && this.isDataEqualToDate(this.form.get("endDate").value, new Date(x.payDate))
    );
}

changeHotel() {
    this.dsHotels.data = this.filterHotels("value");
}

changeRegion() {
    this.dsHotels.data = this.filterRegions("value");
}

changeDate() {
    this.dsHotels.data = this.getFilteredDate();
}


filterAge() {
    //this.dsHotels.data = this.hotels.filter(x => x.numberOfAd == this.form.get("adult").value && x.numberOfChd == this.form.get("chd").value);
    this.dsHotels.data = this.hotels.filter(x => x.numberOfAd == x.numberOfChd);
}

search() {
    this.showList = true;
    this.filterHotels("");
    this.filterRegions("");
    this.changeDate();
}

1 个答案:

答案 0 :(得分:1)

使用reactive forms创建表单时,您可以从模板中的事件绑定切换

< ... (change)="changeHotel()" 
< ... (ngModelChange)="changeDate()">

在课堂上做。

ngOnInit() {
  // ... initial logic
  this.form.get('name').valueChanges.subscribe(this.changeHotel.bind(this))
  this.form.get('region').valueChanges.subscribe(this.changeRegion.bind(this))
  this.form.get('startDate').valueChanges.subscribe(this.changeDate.bind(this))
  this.form.get('endDate').valueChanges.subscribe(this.changeDate.bind(this))
  this.form.get('adult').valueChanges.subscribe(this.filterAge.bind(this))
  this.form.get('chd').valueChanges.subscribe(this.filterAge.bind(this))
}

诸如FormGroup和FormControl之类的反应性表单实例具有一个 valueChanges方法,该方法返回发出最新的Observable 价值观。因此,您可以订阅valueChanges以更新实例 变量或执行操作。

source

相关问题