【问题标题】:Detect angular template if/else change检测角度模板 if/else 变化
【发布时间】:2019-09-12 02:09:59
【问题描述】:

我有一个模板,它使用 Angulars 条件模板逻辑来显示动态内容。条件的值根据异步函数的响应而变化。在函数返回一个值后,我想追加一个新元素。问题是,当我这样做时,会在模板更改之前附加新元素,从而有效地删除附加的元素。

看看这个 stackblitz 的例子:https://stackblitz.com/edit/angular-aty1zz

app.component.ts

export class AppComponent implements AfterViewInit  {
  private hasAsyncResponded;
  private p: HTMLParagraphElement;

  async ngAfterViewInit() {
    this.hasAsyncResponded = await this.getAsyncThing();
    this.p = document.createElement('p');
    this.p.textContent = 'foo bar baz';
    document.getElementsByClassName('my-div')[0].appendChild(this.p);
    // debugger;
  }

  get shouldShowTemplateTwo(): boolean {
    return this.hasAsyncResponded ? true : false;
  }

  async getAsyncThing(): Promise<boolean> {
    const promise: Promise<boolean> = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(true);
      }, 3000);
    });
    return promise;
  }
}

app.component.html

<ng-container *ngIf="shouldShowTemplateTwo; then templateTwo else templateOne"></ng-container>
<ng-template #templateOne>
  <div class="my-div">
    <h1>Template 1</h1>
  </div>
</ng-template>
<ng-template #templateTwo>
  <div class="my-div">  
    <h1>Template 2</h1>
  </div>
</ng-template>

在 app.component.ts 的第 9 行,我定义了一个名为 hasAsyncResponded 的变量,默认情况下它是假的(未定义)。

在第 13 行,我等待来自异步函数的响应并将其存储为 hasAsyncResponded 的值。

在第 20 行,我创建了一个 getter,模板使用它来有条件地显示所需的 ng-template(app.component.html:第 1 行)。

在 promise 解决之后,hasAsyncResponded 的值设置为 true,这会切换 ng-template。同样在 promise 解决后,我们进入 app.component.ts 的第 16 行,它在模板中附加了一个新段落。

由于承诺已经解决并且hasAsyncResponded 的值在添加新段落之前已更新,我希望新段落将附加到更新的模板 (#templateTwo)。但是,该段落会附加到前一个模板 (#templateOne)。如果您在 app.component.ts 的第 17 行取消注释调试器,您可以看到这一点。当调试器暂停代码执行时,#templateOne 可见,附带段落,恢复代码执行后,#templateTwo 显示。

如何将段落附加到正确的模板中?我想也许我只需要在添加新段落之前检测更改,但这并不能解决问题。

【问题讨论】:

    标签: angular ng-template angular-changedetection


    【解决方案1】:

    这就是异步管道的用途,将承诺分配给组件上的属性并在模板中使用异步管道。

    <ng-container *ngIf="yourPromise | async; then templateTwo else templateOne">
    

    无需订阅 TypeScript 中的承诺

    【讨论】:

      【解决方案2】:

      我最终决定我把问题复杂化了。

      我创建了一个新属性 shouldShowTemplateTwo,它默认为 false,并在等待的承诺解决时设置为 true。

      【讨论】:

        猜你喜欢
        • 2023-03-11
        • 2021-06-17
        • 1970-01-01
        • 2021-08-07
        • 2018-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-07
        相关资源
        最近更新 更多