对点击事件的反应延迟

时间:2017-01-31 00:22:16

标签: angular firebase angularfire2

我有一个带有Add按钮的组件,它将转到数据库,添加一条新记录,然后更新可观察的数据。添加新记录的功能是在添加新记录后解析的Promise。当组件到达数据库时,我想隐藏添加按钮,直到添加新记录。模板和组件大致如下:

模板

<table>
...
</table>

<button (click)="addRow()" *ngIf="!addingRow">Add New</button>

组件类(打字稿)

export class AuctionComponent {
  addingRow: boolean = false;

  addRow() {
    this.addingRow=true;
    console.log('Adding Row');
    this.salesSvc.addBid()
      .then(()=> {
        this.addingRow = false;
        console.log('finished');
       });
  }
}

添加新记录的承诺大约在一秒钟内解决。这就是我认为会发生的事情:

  • 点击添加按钮
  • {button disappears}
  • &#34;添加行&#34;显示在控制台中
  • {等待承诺解决}
  • {button reappears}
  • &#34;成品&#34;显示在控制台中

以下是实际发生的事情:

  • 点击添加按钮
  • &#34;添加行&#34;显示在控制台中
  • {等待承诺解决的问题}
  • &#34;成品&#34;显示在控制台中
  • {按钮短暂消失&amp;重新出现}

我尝试过使用ngZone.run(),ChangeDetectorRef .markForCheck()&amp; .detectChanges()和setTimeout()。我还参与了DefaultDetectionStrategy of Default&amp; OnPush。我错过了什么?

更新

因此,承诺是将数据保存到firebase。与解决firebase中的承诺有关的事情似乎正在阻止这一点。

我将组件更改为只测试它的promise部分:

export class AuctionComponent {
  addingRow: boolean = false;

  addRow() {
    this.addingRow=true;
    console.log('Adding Row');
  //  this.salesSvc.addBid()
    this.promise()
      .then(()=> {
        this.addingRow = false;
        console.log('finished');
       });
  }

  promise() {
    return new Promise((resolve, reject) => {
      setTimeout(resolve, 2000);
    });
  }
}

这样做会使按钮的行为与我预期的一样。

服务中的addBid方法如下所示(this.af是AngularFire):

  addBid(sale: ISale) {
    return this.af.database.list(`sales/${sale.year}/bids`)
        .push({lot: null, price: 0, description: ''});
  }

所以我认为也许事情会发生在承诺的火焰基础上,所以我把所有事情都包含在我自己的承诺中:

  addBid(sale: ISale) {
    return new Promise((resolve, reject) => {
      this.af.database.list(`sales/${sale.year}/bids`)
        .push({lot: null, price: 0, description: ''})
        .then(() => resolve())
        .catch(() => reject());
    });   
  }

但是,我仍然得到延迟回应。 firebase / angularfire2中是否存在导致重绘不发生的事情?

2 个答案:

答案 0 :(得分:0)

你可以做的是,当你从服务器获得响应时将它存储在某个变量中并制作另一个get方法,该方法将返回true或false,具体取决于你将收到的数据长度。因此,当您拥有数据时,您将拥有数据的长度,在这种情况下返回true,否则为false。将此get方法绑定到按钮。

第二个选项:最初您将变量设置为true(单击按钮时)这是正确的。现在在get方法中,当你有数据长度时,可以将此变量返回为false / true(取决于隐藏/显示的逻辑)。

我认为这应该适合你的情况。

答案 1 :(得分:0)

为了它的价值,我能够通过在setTimeout()中包装addRow的promise部分来实现这一点。我仍然不确定为什么需要它或为什么它有用,所以我很乐意在那个领域得到一些反馈或指导。

  addRow() {
    this.addingRow = true;
    setTimeout(() => {
      this.salesSvc.addBid(this.sale)
        .then(() => {
          this.addingRow = false;
        });
    }, 0);