【问题标题】:Angular2 wait until one component subscription completesAngular2 等到一个组件订阅完成
【发布时间】:2017-03-15 14:51:27
【问题描述】:

我有自定义组件,它在初始化时从数据服务获取国家和集合。如何将已完成工作的消息传递给另一个组件?

  • PeopleParentComponent - 保存搜索模型并在初始化时将数据发送到网格(在构造函数中有 PeopleDataService)
    • SearchChildComponent - SearchModel
      • CountrySelectorComponent - SearchModel.Country - 在 Init 上从 commonDataService 获取数据并为用户设置正确的国家/地区
    • GridChildComponent - 从父级接收数据

当 PeopleParentComponent 运行时,它会构建 SearchChildComponent -> CountrySelectorComponent。同样在初始化期间,它从 peopleDataService 获取网格数据,但搜索模型不完整,因为 CountrySelectorComponent 正在获取其国家和选定的国家。我可以在搜索组件归档后运行它并手动获取消息,但是设置完之后怎么做呢?

将消息发布到 ParentComponent 的东西 -> 我们已经完成了获取搜索数据,您可以获取网格数据。

编辑:

国家选择组件

 @Component({
 selector: 'country-select',
 template: ` //wrapper around custom select`,
 providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: CountrySelectComponent, multi: true,}]
 })
 export class CountrySelectComponent implements ControlValueAccessor, OnInit {
     private data : CountryModel[]
     private countryModel : CountryModel;
     constructor(private commonDataService : CommonDataService){}
     ngOnInit(){
     this.commonDataService.getCountires().subscribe(
         data => {this.data = data; this.value = data[0]}) //gets data from server and sets the first value
     }
 {
 ... implemetation of ControlValueAccessor

搜索组件

 @Component({
     selector: 'people-search',
     tempalte: `
         <country-select ngModel]="value?.country" (ngModelChange)="value?.country? value.country= $event : null"'></country-select>
         //Some other controllers like country select`
         <button (click)='performSearch()
     }),
     providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: SearchComponent , multi: true,}]
 export class SearchComponent implements ControlValueAccessor {
     @Output() searchEmitter = new EventEmitter(); 
     peroformSearch(){
         this.searchEmitter.emit(true)//the data is inside Model so it passes just boolean to run a method in Parent - this could be changed?
     }
     ... implemetation of ControlValueAccessor
 }

父组件

@Component({
selector: 'people',
template: `
<people-search [(ngModel)]='searchModel' (searchEmitter)='perform'></people-search>
<people-grid [gridDataStore]='gridDataStore'></people-grid>
`
})
export class PeopleComponent implements onInit{
searchModel : PeopleSearchModel = new PeopleSearchModel();
gridDataStore : CustomStore;

constructor(private peopleService : PeopleService){}
ngOnInit(){
this.gridDataStore = new CustomStore({
    load : (opts) => {
        //some paging and sorting
        return this.peopleService.getPeople(this.searchModel).toPromise().then(data =>{
            return { data : data.data, totalCount : data.totalCount} }}}) //Fetches the grid data before the search model is complete !
    }
}

编辑2: 我试图在路由上创建解析器。

@Injectable()
export class CommonDataCountryResolver implements Resolve<Country[]> {

constructor(private commonService: CommonDataService, private router: Router) { }
resolve(route: ActivatedRouteSnapshot): CountryModel[] | Promise<CountryModel[]> | Observable<CountryModel[]> {
    return this.commonService.getCountries().toPromise().then(countries=> {
        if (countries) {
            return countries;
        } else { //not found
            this.router.navigate(['/home']);
            return false;
        }
    });
}

}

路线

...
 children: [
 { path: 'People', component: PeopleComponent, resolve: { countries: CommonDataCountriesResolver } },
...

现在 CountrySelectorComponents 得到了

constructor(private route: ActivatedRoute,

ngOnInit() {
    this.route.data.subscribe(
        (data: { countries: any }) => {
            this.data = data.countries;
            if (data)
                this.value = data.countries[0];
        }
    );

它可以工作,但仍然有问题。

  1. 解析器的 ngInit 排在第一位,给我列表
  2. 父组件的ngInit启动...这很糟糕,因为它尝试使用搜索模型更新网格。
  3. SearchComponent 的 nhInit 和 Child - CountrySelectorComponent 的 ngInit。

编辑3:

我更接近答案。 我已将发射器添加到搜索组件,它在 ngAfterViewInit() 上发射,这是在设置所有组件之后,并添加 *ngIf 以在父级中创建网格。

但这给了我另一个问题: 我的国家/地区数据列表运行良好,并在开始时设置了 [0] 元素,但之后我从搜索组件中获得了 ngModel,该组件覆盖了使用空模型选择的国家/地区。

【问题讨论】:

  • 请出示代码

标签: angular rxjs observable


【解决方案1】:

向 ParentComponent 发送消息的东西 -> 我们完成了 通过获取数据进行搜索,您可以获取网格数据。

在子组件中:

@Component({
  selector: 'child-complnent',
})
export class childComponent implements OnInit {
  @Output() notifyThatWorkIsComplete = new EventEmitter();

  ngOnInit() {
    // get data for search and when it's complete do
    this.notifyThatWorkIsComplete.emit();
  }

  constructor(){}
}

在父组件的模板中放类似

<child-component (notifyThatWorkIsComplete)="getDataForGrid()"></child-component>

【讨论】:

  • 我想到了这个简单的答案。所以我的子组件(countrySelect)会向搜索组件提供有关完成的信息,它会向父组件提供相同的信息,然后当父组件完成时,*ngIf 将生成网格组件。但是对于许多子组件,搜索会包含很多方法,它可以在 ngModel 中传递布尔值,例如:Countries[]、selectedCountry、isActive ...但它仍然看起来不太好。
猜你喜欢
  • 2017-09-29
  • 1970-01-01
  • 2019-03-24
  • 1970-01-01
  • 2023-03-07
  • 2021-04-13
  • 2016-11-17
  • 1970-01-01
相关资源
最近更新 更多