【问题标题】:Delayed reaction to click event对点击事件的延迟反应
【发布时间】:2017-01-31 00:22:15
【问题描述】:

我有一个带有添加按钮的组件,它将转到数据库,添加一条新记录,然后更新 observable 的数据。添加新记录的函数是一个 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');
       });
  }
}

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

  • 点击添加按钮
  • {按钮消失}
  • “添加行”显示在控制台中
  • {等待承诺解决}
  • {按钮重新出现}
  • “完成”显示在控制台中

这是实际发生的事情:

  • 点击添加按钮
  • “添加行”显示在控制台中
  • {等待承诺解决}
  • “完成”显示在控制台中
  • {按钮短暂消失并重新出现}

我尝试过使用 ngZone.run()、ChangeDetectorRef .markForCheck() & .detectChanges() 和 setTimeout()。我也玩过 Default & OnPush 的 ChangeDetectionStrategy。我错过了什么?

更新

所以承诺是伸出援手并将数据保存到 Firebase。与解决 firebase 中的承诺有关的事情似乎阻碍了这一点。

我更改了组件以仅测试它的承诺部分:

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 中是否存在导致重绘未发生的问题?

【问题讨论】:

  • 尝试
  • 测试了你的代码,对我来说它的工作原理应该......?
  • @CleanCrispCode 好建议...我试过了,但得到了相同的结果。
  • @AJT_82 我以前在其他 Angular2 项目中做过这个,没有任何问题,但我不太明白为什么它在这里不起作用。我假设我遇到了某种变化检测优化,但我不知道为什么我现在会遇到它。
  • @jloosli 是的,如前所述,我测试了您的代码,它工作正常,一定还有其他事情发生。如果您尝试在 plunker 中重现问题,这可能会缩小范围,以便更容易地找到问题,如果它在 plunker 中有效:)

标签: angular firebase angularfire2


【解决方案1】:

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

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

我认为这应该适用于您的情况。

【讨论】:

    【解决方案2】:

    对于它的价值,我能够通过将 addRow 的 promise 部分包装在 setTimeout() 中来实现它。我仍然不确定为什么需要这样做或为什么它会起作用,所以我很想在该领域获得一些反馈或方向。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多