当函数与ngIf一起使用时,更改检测无限运行

时间:2017-03-08 18:56:35

标签: angularjs angular ionic-framework

我正在开展Ionic 2项目。模板有一个ngIf来检查它是否是正确的用户。

show.ts

  constructor( public book: Bookemon ){}
  rightUser(){
    console.log('right user');
    return this.book.rightUser(this.hunt.user.id);
  }

bookemon.tsbookemonauth是服务)

  rightUser(id: number){
    return this.auth.user.id === id;
  }

show.html

<ion-content  fullscreen="true">
  <div id="image-modal" >
    <img [src]="imageSource(hunt.picture_url)" (click)="dismissModal()" >
    <button ion-fab mini *ngIf = " !hunt.picture_url " (click)="showEditHuntModal()" color="ionic">
      <ion-icon  name="add" ></ion-icon>
    </button>
    <button color="danger" class="new-claim" ion-button round icon-left *ngIf = "rightUser() && hunt.claims.length " (click)="openClaimModal(hunt)">
      <ion-icon name="trophy"></ion-icon>
      New Claim
    </button>
  </div>
  <div class="hunt-content">
    <button small clear ion-button icon-only class="options" *ngIf="rightUser()" (click)="presentAction()">
      <ion-icon name="md-more"></ion-icon>
    </button>
    <hunt [hunt]="hunt" [huntedUser]="huntedUser" ></hunt>
  </div>
  <ion-fab *ngIf="hunt.dfu !== undefined" bottom (click)="dismissModal('rejected')"   class="close-fab">
    <button ion-fab   color="danger" ><ion-icon  name="close" ></ion-icon></button>
  </ion-fab>
  <ion-fab *ngIf="hunt.dfu !== undefined" bottom (click)="dismissModal('accepted')"  class="heart-fab">
    <button ion-fab  color="primary"    ><ion-icon  name="heart" ></ion-icon></button>
  </ion-fab>
</ion-content>

模板会根据*ngIf = "rightUser()"

显示一些内容

一切正常,但控制台记录的是来自right user函数的无限多 rightUser()。预期的行为应该在控制台中记录right user一次,并且不再运行更改检测。

ngIf中使用函数是不好的做法?什么是无限次触发变化检测?

修改

我在一个新项目中尝试了ngIf的函数,并且它无法无限次地运行更改检测。我不确定这里是什么造成的。如果有帮助,这是我的show.ts

export class ShowPage {
  hunt: Hunt ;
  huntedUser: User;
  editHuntPage= EditHuntPage;
  claimHuntPage = ClaimHuntPage;
  rightUser: Boolean;
  constructor(public alert: AlertController , public modal: ModalController, public events: Events
    , public toastCtrl: ToastController, private navParams: NavParams , public action: ActionSheetController
    , public book: Bookemon , public viewCtrl: ViewController, public nav: NavController) {
    console.log(navParams.data);
    this.hunt = navParams.data.hunt;
    this.rightUser = this.book.rightUser(this.hunt.id);
  }
  ionViewDidLoad(){
    console.log('view');
    if(this.hunt.status == "hunted"){
      this .book.getHuntedUser(this.hunt).subscribe( (res) => {
        this.huntedUser = res.json();
        console.log(this.huntedUser);
      })
    }
  }
  imageSource(pic: string){
    return pic ? pic : CONFIG.noHuntPic ;
  }
  dismissModal(status?: string){
    console.log('dismiss');
    this.viewCtrl.dismiss(status);
  }
  presentAction(){
    let actionSheet = this.action.create(
    {
      title: this.hunt.title ,
      buttons: [
      {
        text: 'Edit',
        handler: () => {
          let trans = actionSheet.dismiss();
          trans.then( () => {
            this.showEditHuntModal();
          })
          return false;
        }
      },
      {
        text: 'Delete',
        role: 'destructive',
        handler: () => {
          let trans = actionSheet.dismiss();
          trans.then( () => {
            this.deleteAlert();
          })
          return false;
        }
      },
      {
        text: 'Cancel',
        role: 'cancel',
      }
      ]
    })
    actionSheet.present();
  }
  showEditHuntModal(){
    let modal = this.modal.create(EditHuntPage,this.hunt);
    modal.present();
    modal.onDidDismiss( (data) => {
      if(data){
        this.hunt = data;
      }
    })
  }
  deleteAlert(){
    let alert = this.alert.create({
      title: 'Confirm',
      message: 'Do you want to delete this hunt?',
      buttons: [{
        text: "Delete",
        handler: () => { this.deleteHunt() }
      }, {
        text: "Cancel",
        role: 'cancel'
      }]
    })
    alert.present();
  }
  deleteHunt(){
    this.book.deleteHunt(this.hunt.id).subscribe( (res) => {
      // this.events.publish("user-hunts:deleted",this.hunt);
      this.viewCtrl.dismiss("deleted",this.hunt);
    }, (err) => {
      this.handleError(err);
    })
  }
  openClaimModal(hunt){
    let claimModal =  this.modal.create(ShowClaimPage,{hunt: hunt})
    claimModal.present();
  }
   rightUser(){
     console.log('right user');
     return this.book.rightUser(this.hunt.user.id);
  }
  handleError(err){
    console.log(err);
    let error= err.message ? err.message : "Error occured";
    let toast = this.toastCtrl.create({ message: error, duration: 2000 , position: 'top'});
    toast.present();
  }

}

1 个答案:

答案 0 :(得分:0)

angular使用zones.js检测你的应用中是否有变化,这样每次都会检查ngIf,你可以这样:

 <button small clear ion-button icon-only class="options" *ngIf="isRightUser" (click)="presentAction()">
      <ion-icon name="md-more"></ion-icon>
 </button> 
//...
<button small clear ion-button icon-only class="options" *ngIf="isRightUser" (click)="presentAction()">


   //show.ts
   isRightUser:boolean;
   constructor( public book: Bookemon ){}
   ngOnInit(){
     this.isRightUser= rightUser();
   }

   rightUser(){
      return this.book.rightUser(this.hunt.user.id);
   }