有没有办法在服务初始化加载其他组件之前等待? 我需要在显示组件(需要数据)之前同步加载一些数据,我不想使用promises / observables(使用那些用于异步调用)
ngIf似乎没有削减它(组件加载即使如果不匹配)。
我没有使用路由器(不需要它用于应用程序),所以我不认为@CanActivate在这种情况下是合适的。
有什么想法吗?
@Component({
selector: 'my-app',
directives: [MyDirective],
template: `
<div>
<div *ngIf="!initialized">Loading...</div>
<div *ngIf="initialized"><myDirective>should wait for service to be initialized</myDirective></div>
</div>`
})
export class AppComponent {
initialized = false;
constructor(_myService: MyService) {
this._myService = _myService;
}
ngOnInit() {
this._myService.init()
.then(() => {
setTimeout( () => this.initialized = true, 2000);
}
);
}
}
答案 0 :(得分:2)
我不确定我是否正确理解了这个问题,但是从我得到的结果来看,我认为你可以创建一个带有初始值的模型实例(占位符),并允许你的组件使用这个模型初始化,然后,当您的数据准备就绪,更改模型实例值,这将反映到您的组件。
这样,您的组件不需要等待,它只是使用占位符数据,您当然可以在组件内部进行测试,并相应地显示您的模板,以及何时从父级准备好数据,更新它,将更新孩子。
我希望这会有所帮助。
答案 1 :(得分:1)
您使用的是什么版本的Angular?不确定您是否复制了经过修改的代码,但似乎您错过了类中的implements
关键字。
*ngIf
在此plunker中效果很好。
从我收集的内容来看,像@ ngIf这样的东西是在Ng2中做事的正确方法。基本上,只有在条件好的情况下才显示组件。
您可能会陷入困境,因为您的组件在您预期之前会实例化 - 因为您需要在父组件中使用它。
这可能是因为您的组件本身(或模板)需要一些值,但它们不存在(因此您的constructor
会崩溃)。
根据Lifecycle Hooks上的angular.io页面,这正是OnInit界面的用途。
这是直接来自plunker的代码(你的是SubComponent):
import {Component, OnInit} from 'angular2/core'
@Component({
selector: 'sub-component',
template: '<p>Subcomponent is alive!</p>'
})
class SubComponent {}
@Component({
selector: 'my-app',
providers: [],
template: `
<div>
<h2>Hello {{name}}</h2>
<div *ngIf="initialized">
Initialized
<sub-component>Sub</sub-component>
</div>
<div *ngIf="!initialized">Not initialized</div>
</div>
`,
directives: [SubComponent]
})
export class App implements OnInit {
initialized = false;
constructor() {
this.name = 'Angular2'
}
ngOnInit() {
setTimeout(() => {
this.initialized = true;
}, 2000)
}
}
答案 2 :(得分:0)
我通常做的是在我的数据服务中创建EventEmitter
,然后在执行任何操作之前允许每个组件监听dataLoaded
事件。它可能不是解决这个问题的最有效和“教科书”方式,但效果很好。例如,在app.component.ts
(我最父的组件)中,我在ngOnInit
挂钩中加载数据。首先,让我们看看我们的数据服务:
data.service.ts
@Injectable()
export class DataService {
dataLoaded = new EventEmitter<any>();
prop1: string;
prop2: string;
constructor(private http: HttpClient) {}
// Asynchronously returns some initialization data
loadAllData () {
return this.http.get<string>('/api/some-path');
}
}
app.component.ts
export class AppComponent {
constructor (private dataService: DataService) {
}
ngOnInit() {
this.dataService.loadAllData().subscribe((data) => {
// Maybe you want to set a few props in the data service
this.dataService.prop1 = data.prop1;
this.dataService.prop2 = data.prop2;
// Now, emit the event that the data has been loaded
this.dataService.dataLoaded.emit();
});
}
}
现在我们在主应用程序组件中加载DataService
并发出“已加载”事件,我们可以在子组件中订阅此事件:
@Component({
selector: 'child-component',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
constructor(private dataService: DataService) {
this.dataService.dataLoaded.subscribe(() => {
// Once here, we know data has been loaded and we can do things dependent on that data
this.methodThatRequiresData();
});
}
methodThatRequiresData () {
console.log(this.dataService.prop1);
}
}