基于离子搜索,UI值不会在ngFor中更新

时间:2017-10-08 08:50:37

标签: angular ionic-framework ionic2 ionic3 angular-filters

我的HTML代码

  <ion-searchbar (ionInput)="getFilteredItems($event)"></ion-searchbar>

    <button ion-item *ngFor="let patient of surveyPatients" (click)="showPatientData(patient)">{{patient.name}} - {{patient.age}} - {{patient.idCardNumber}}</button>

对应的ts代码

surveyPatients:any;

getFilteredItems(ev: any) {    
    this.initializeSurveyPatients();
    let val = ev.target.value;

    console.log(this.surveyPatients.length);   

    if (val && val.trim() != '' ) {
      this.surveyPatients = this.surveyPatients.filter((item) => {
        return (item.name.toLowerCase().indexOf(val.toLowerCase()) > -1);
      })
       console.log(this.surveyPatients.length); 
    }
  }


initializeSurveyPatients() {


        this.afoDatabase.list('/SurveyPatients',
      {
        query:{
              orderByChild: 'district',
              equalTo: 'Nalgonda '
            }
      }

      ).subscribe(snap => {

      this.surveyPatients = snap;
    });


  }

当我看到 console.log(this.surveyPatients.length); 的值 getFilteredItems()方法时,我在过滤器之前和之后获得预期值,这证实了我们过滤器工作正常。

但是在过滤操作之后,UI中的列表没有相应地更新。

我不确定我想要添加什么。

请帮我解决这个问题。

1 个答案:

答案 0 :(得分:2)

我认为情况是您的过滤器在Firebase获取列表项之前被调用,并且当他获取它时重新初始化过滤后的数组。你需要做这样的事情:

surveyPatients:any;

getFilteredItems(ev: any) {
  let val = ev.target.value;
  this.initializeSurveyPatients().subscribe(snap => {
    this.surveyPatients = snap;

    console.log(this.surveyPatients.length);   

    if (val && val.trim() != '' ) {
      this.surveyPatients = this.surveyPatients.filter((item) => {
        return (item.name.toLowerCase().indexOf(val.toLowerCase()) > -1);
      })
      console.log(this.surveyPatients.length); 
    }
  });
}


initializeSurveyPatients() {
  return this.afoDatabase.list('/SurveyPatients', {
    query:{
          orderByChild: 'district',
          equalTo: 'Nalgonda '
        }
  });
}

通过这种方式,您将等待数据库查询结束,以便您可以过滤itens。

如果你在html输入上使用了一个事件,那么每当用户输入一个过滤的字母时,你的firebase方法就可以多次调用并重新加载你的病人名单。

另外一件事,我自己从未使用过AngularFire2,但是订阅列表并不意味着你在数据库的那个节点中有一个observable?这很糟糕,因为你的对象可以在没有进一步警告的情况下重新设置,这真的很糟糕。

您应该有2个患者变量,一个用于每次更新时接收数据库结果,另一个用于过滤器:

surveyPatients:any; // to be observed
surveyPatientsFiltered: any; // to be used in filter

ionViewWillLoad(){ // WHEN LOADING OR ENTERING PAGE YOU'LL SUBSCRIBE TO THE EVENT AND SAVE THE RESULTS IN YOUR VAR
  this.afoDatabase.list('/SurveyPatients',
  {
    query:{
          orderByChild: 'district',
          equalTo: 'Nalgonda '
        }
  }).subscribe(snap => {
    this.surveyPatients = snap;
  });
}

getFilteredItems(ev: any) {    
    this.initializeSurveyPatients();
    let val = ev.target.value;

    console.log(this.surveyPatients.length);   

    if (val && val.trim() != '' ) {
      this.surveyPatientsFiltered = this.surveyPatientsFiltered.filter((item) => {
        return (item.name.toLowerCase().indexOf(val.toLowerCase()) > -1);
      })
       console.log(this.surveyPatients.length); 
    }
  }

initializeSurveyPatients(){
  this.surveyPatientsFiltered = this.surveyPatients;
}

有了这个,您的过滤器将更快,因为您不必等待firebase结束查询,没有并发问题,并且您的surveyPatients将始终更新,而无需用户在过滤时手动更新它。

希望这会有所帮助。