如何仅在标签为“*ngIf=true”时才初始化组件?
How to init a component only when its tag is at `*ngIf=true`?
更新:
Günter Zöchbauer 提供了一个非常可以接受的完美答案(谢谢!)。但是我仍然有一个问题要检查我正在做的事情是否是获得我想要的结果的正确方法。上下文如下。
我对父视图上的自定义标记的期望是,当 *ngIf
条件为假时,根本不会加载组件(或者可能是大部分组件)。即使不在DOM(因为条件为false),它仍然被加载是正常的吗?有没有更好的方法将组件的模板(及其 class 的逻辑)嵌入到父组件的模板中?
原版post
我是 Angular 2 的新手,到目前为止,我在开发基于 Spotify API.
的小型歌曲曲目元数据应用程序时非常开心
TL;DR: 如何仅在其对应的 HTML 标记(使用 selector
属性 定义时初始化组件 @Component
) 如果 *ngIf="true"
?
但我当然面临困难!我有这个组件 TrackDetailComponent
,我想在其模板中包含另外 2 个组件。单击按钮时,它会从一个内部组件切换到另一个。
这是模板的样子(请注意,我现在只开发了两个内部组件之一,所以我使用占位符代替第二个):
<div id="view">
<tig-track-info *ngIf="childView == TrackDetailView.InfoView" [track]="track"></tig-track-info>
<p *ngIf="childView == TrackDetailView.LyricsView">Here go the lyrics</p>
</div>
如您所见,我的内部组件(名为 TrackInfoComponent
)有一个输入参数。这是该组件的摘录:
@Component({
selector: "tig-track-info",
templateUrl: "app/components/track-info/track-info.component.html",
styleUrls: ["app/components/track-info/track-info.component.css",
"app/shared/animations.css"]
})
export class TrackInfoComponent implements OnInit {
private _trackId: string = null;
@Input()
track: Track = null;
previewAudio: any = null; // The Audio object is not yet defined in TypeScript
albumArtworkLoaded: boolean = false;
...
}
我真正的问题不是将 TrackInfoComponent
嵌入另一个,而是同步它们。 TrackDetailComponent
异步调用 API,然后初始化 track
属性。但是 TrackInfoComponent
还需要初始化 track
才能完成它的工作,否则我会得到空引用异常(这是合乎逻辑的)。
我尝试在 ngOnInit()
中设置子组件数据并仅在 track
准备就绪时将其父模板的 *ngIf
设置为 true 但似乎 ngOnInit()
立即被调用,即使 DOM 元素 tig-track-info
没有显示 *ngIf
.
我想我可以在子组件中使用事件或我自己的 init 方法,仅在我准备好时调用,但我想知道是否有更好的方法使用 Angular 2个组件生命周期挂钩或为此推荐的任何其他方法。有人对此有任何想法吗?
谢谢:-)
您可以使用 OnChanges,每当 @Input()
属性 值被模板绑定更改时调用 OnChanges `[track]="..."
export class TrackInfoComponent implements OnChanges {
ngOnChanges(changes: SimpleChanges) {
if(this.track) {
...
}
}
}
1)第一步
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
在您的代码中添加 ChangeDetectorRef
2) 第二步
constructor(private changeDetector : ChangeDetectorRef){
}
3) 只要你的 *ngIf="condition" 发生变化,即条件变为真,那么
你可以打电话
if(true==condition){
this.changeDetector.detectChanges();
}
4) 这将呈现您的 html 模板。
你可以试试这个,如果它适合你。
更新:
Günter Zöchbauer 提供了一个非常可以接受的完美答案(谢谢!)。但是我仍然有一个问题要检查我正在做的事情是否是获得我想要的结果的正确方法。上下文如下。
我对父视图上的自定义标记的期望是,当 *ngIf
条件为假时,根本不会加载组件(或者可能是大部分组件)。即使不在DOM(因为条件为false),它仍然被加载是正常的吗?有没有更好的方法将组件的模板(及其 class 的逻辑)嵌入到父组件的模板中?
原版post
我是 Angular 2 的新手,到目前为止,我在开发基于 Spotify API.
的小型歌曲曲目元数据应用程序时非常开心TL;DR: 如何仅在其对应的 HTML 标记(使用 selector
属性 定义时初始化组件 @Component
) 如果 *ngIf="true"
?
但我当然面临困难!我有这个组件 TrackDetailComponent
,我想在其模板中包含另外 2 个组件。单击按钮时,它会从一个内部组件切换到另一个。
这是模板的样子(请注意,我现在只开发了两个内部组件之一,所以我使用占位符代替第二个):
<div id="view">
<tig-track-info *ngIf="childView == TrackDetailView.InfoView" [track]="track"></tig-track-info>
<p *ngIf="childView == TrackDetailView.LyricsView">Here go the lyrics</p>
</div>
如您所见,我的内部组件(名为 TrackInfoComponent
)有一个输入参数。这是该组件的摘录:
@Component({
selector: "tig-track-info",
templateUrl: "app/components/track-info/track-info.component.html",
styleUrls: ["app/components/track-info/track-info.component.css",
"app/shared/animations.css"]
})
export class TrackInfoComponent implements OnInit {
private _trackId: string = null;
@Input()
track: Track = null;
previewAudio: any = null; // The Audio object is not yet defined in TypeScript
albumArtworkLoaded: boolean = false;
...
}
我真正的问题不是将 TrackInfoComponent
嵌入另一个,而是同步它们。 TrackDetailComponent
异步调用 API,然后初始化 track
属性。但是 TrackInfoComponent
还需要初始化 track
才能完成它的工作,否则我会得到空引用异常(这是合乎逻辑的)。
我尝试在 ngOnInit()
中设置子组件数据并仅在 track
准备就绪时将其父模板的 *ngIf
设置为 true 但似乎 ngOnInit()
立即被调用,即使 DOM 元素 tig-track-info
没有显示 *ngIf
.
我想我可以在子组件中使用事件或我自己的 init 方法,仅在我准备好时调用,但我想知道是否有更好的方法使用 Angular 2个组件生命周期挂钩或为此推荐的任何其他方法。有人对此有任何想法吗?
谢谢:-)
您可以使用 OnChanges,每当 @Input()
属性 值被模板绑定更改时调用 OnChanges `[track]="..."
export class TrackInfoComponent implements OnChanges {
ngOnChanges(changes: SimpleChanges) {
if(this.track) {
...
}
}
}
1)第一步
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
在您的代码中添加 ChangeDetectorRef
2) 第二步
constructor(private changeDetector : ChangeDetectorRef){
}
3) 只要你的 *ngIf="condition" 发生变化,即条件变为真,那么 你可以打电话
if(true==condition){
this.changeDetector.detectChanges();
}
4) 这将呈现您的 html 模板。
你可以试试这个,如果它适合你。