检测 angular 模板 if/else 变化
Detect angular template if/else change
我有一个使用 Angulars 条件模板逻辑来显示动态内容的模板。条件的值根据异步函数的响应而变化。在函数 returns 一个值之后我想追加一个新元素。问题是,当我这样做时,新元素会在模板更改之前附加,从而有效地删除附加元素。
看一下这个 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 resolve 之后,我们到达 app.component.ts 的第 16 行,它向模板附加了一个新段落。
由于承诺已解决并且 hasAsyncResponded
的值已在追加新段落之前更新,我希望新段落将追加到更新后的模板 (#templateTwo
)。但是,该段落会附加到以前的模板 (#templateOne
)。如果您在 app.component.ts 的第 17 行取消注释调试器,您可以看到这一点。当调试器暂停代码执行时,#templateOne
与附加段落可见,在恢复代码执行后显示 #templateTwo
。
如何将段落附加到正确的模板?我认为也许我只需要在附加新段落之前检测更改,但这并不能解决问题。
这就是异步管道的用途,将承诺分配给组件上的 属性 并在模板中使用异步管道。
<ng-container *ngIf="yourPromise | async; then templateTwo else templateOne">
无需订阅 TypeScript 中的 promise
我最终决定我把问题复杂化了。
我创建了一个新的 属性 shouldShowTemplateTwo
,它默认为 false,并在等待的承诺解决时设置为 true。
我有一个使用 Angulars 条件模板逻辑来显示动态内容的模板。条件的值根据异步函数的响应而变化。在函数 returns 一个值之后我想追加一个新元素。问题是,当我这样做时,新元素会在模板更改之前附加,从而有效地删除附加元素。
看一下这个 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 resolve 之后,我们到达 app.component.ts 的第 16 行,它向模板附加了一个新段落。
由于承诺已解决并且 hasAsyncResponded
的值已在追加新段落之前更新,我希望新段落将追加到更新后的模板 (#templateTwo
)。但是,该段落会附加到以前的模板 (#templateOne
)。如果您在 app.component.ts 的第 17 行取消注释调试器,您可以看到这一点。当调试器暂停代码执行时,#templateOne
与附加段落可见,在恢复代码执行后显示 #templateTwo
。
如何将段落附加到正确的模板?我认为也许我只需要在附加新段落之前检测更改,但这并不能解决问题。
这就是异步管道的用途,将承诺分配给组件上的 属性 并在模板中使用异步管道。
<ng-container *ngIf="yourPromise | async; then templateTwo else templateOne">
无需订阅 TypeScript 中的 promise
我最终决定我把问题复杂化了。
我创建了一个新的 属性 shouldShowTemplateTwo
,它默认为 false,并在等待的承诺解决时设置为 true。