Angular 2:如何在变化检测时从一个组件传递值以刷新另一个组件?
Angular 2: How to pass value from one component to refresh another component on change detection?
所以我在搜索字段中使用 ng2-bootstrap typeahead。当我 select 返回一个值时,我希望它使用来自 selected 项目的详细信息刷新下面的窗格。
在我的父组件中,我有这个:
HTML:
<input [(ngModel)]="asyncSelected"
[typeahead]="dataSource"
(typeaheadLoading)="changeTypeaheadLoading($event)"
(typeaheadNoResults)="changeTypeaheadNoResults($event)"
(typeaheadOnSelect)="onSelectSearchValue($event)"
[typeaheadOptionsLimit]="7"
[typeaheadMinLength]="3"
[typeaheadWaitMs]="500"
[typeaheadOptionField]="'name'"
name="searchField"
class="form-control" style="width: 250px;" placeholder="Search Chip Families">
...
<div class="container-fluid">
<router-outlet></router-outlet>
</div>
打字稿:
public onSelectSearchValue(e: TypeaheadMatch): void {
this.chipFamilyId = e.item.id;
}
我如何将这个从预输入返回的值传递给我的组件,该组件处理对服务的调用以查找详细信息并将其放入 <router-outlet>
?使用更改检测似乎不起作用。
我的子组件如下:
HTML:
<div class="content" *ngIf='chipFamilies && chipFamilies.length'>
<ol class="breadcrumb">
<li><a [routerLink]="['/home']">Home</a></li>
<li><a [routerLink]="['/chipFamily']">{{chipFamilies.Hierarchy}}</a></li>
<li class="active">{{chipFamilies.Name}}</li>
</ol>
<h2>{{chipFamilies.Hierarchy}}</h2>
...
打字稿:
export class ChipFamilyComponent implements OnInit, OnChanges {
errorMessage: string;
@Input() chipFamilyId: number = 11223;
chipFamilies: IChipFamily[];
constructor(private _adminService: ChipFamilyService) {
}
ngOnInit(): void {
//Initially load 11223 on load
this._adminService.getChipFamily(this.chipFamilyId).subscribe(
chipFamilies => this.chipFamilies = chipFamilies,
error => this.errorMessage = <any>error
);
}
ngOnChanges(changes:{[propKey: string]: SimpleChange}) {
debugger;
this._adminService.getChipFamily(this.chipFamilyId).subscribe(
chipFamilies => this.chipFamilies = chipFamilies,
error => this.errorMessage = <any>error
);
}
}
根据 Harry_Ninh 的极好建议,这是我想出的允许组件之间通信而不使用 @Input 和任何组件选择器的方法:
在我的服务中,我添加了一个主题以允许家长宣布已进行搜索:
@Injectable()
export class ChipFamilyService {
private searchStringSubject = new Subject<string>();
private _searchUrl = 'http://localhost:8888/chipfamily/';
constructor(private _http: Http) {
}
searchAnnounced$ = this.searchStringSubject.asObservable();
announceSearch(searchValue: string) {
this.searchStringSubject.next(searchValue);
}
在我的父组件中,我只是在从我的 typeahead 字段中选择结果后才发布公告:
public onSelectSearchValue(e: TypeaheadMatch): void {
this.chipFamilyService.announceSearch(e.item.id);
}
在我的子组件中,我订阅了公告,然后根据构造函数中的新数据更新模型:
@Component({
template: require('./chip-family.component.html')
})
export class ChipFamilyComponent implements OnInit {
errorMessage: string;
chipFamilyId: number = 11223;
chipFamilies: IChipFamily[];
private gridOptions:GridOptions;
subscription: Subscription;
constructor(private chipFamilyService: ChipFamilyService) {
this.subscription = chipFamilyService.searchAnnounced$.subscribe(
chipFamilyId => {
this.chipFamilyId = Number(chipFamilyId);
this.chipFamilyService.getChipFamily(this.chipFamilyId).subscribe(
chipFamilies => this.chipFamilies = chipFamilies,
error => this.errorMessage = <any>error
);
});
}
这实现了基于预输入搜索使用新数据更新视图面板的预期结果。
所以我在搜索字段中使用 ng2-bootstrap typeahead。当我 select 返回一个值时,我希望它使用来自 selected 项目的详细信息刷新下面的窗格。
在我的父组件中,我有这个:
HTML:
<input [(ngModel)]="asyncSelected"
[typeahead]="dataSource"
(typeaheadLoading)="changeTypeaheadLoading($event)"
(typeaheadNoResults)="changeTypeaheadNoResults($event)"
(typeaheadOnSelect)="onSelectSearchValue($event)"
[typeaheadOptionsLimit]="7"
[typeaheadMinLength]="3"
[typeaheadWaitMs]="500"
[typeaheadOptionField]="'name'"
name="searchField"
class="form-control" style="width: 250px;" placeholder="Search Chip Families">
...
<div class="container-fluid">
<router-outlet></router-outlet>
</div>
打字稿:
public onSelectSearchValue(e: TypeaheadMatch): void {
this.chipFamilyId = e.item.id;
}
我如何将这个从预输入返回的值传递给我的组件,该组件处理对服务的调用以查找详细信息并将其放入 <router-outlet>
?使用更改检测似乎不起作用。
我的子组件如下:
HTML:
<div class="content" *ngIf='chipFamilies && chipFamilies.length'>
<ol class="breadcrumb">
<li><a [routerLink]="['/home']">Home</a></li>
<li><a [routerLink]="['/chipFamily']">{{chipFamilies.Hierarchy}}</a></li>
<li class="active">{{chipFamilies.Name}}</li>
</ol>
<h2>{{chipFamilies.Hierarchy}}</h2>
...
打字稿:
export class ChipFamilyComponent implements OnInit, OnChanges {
errorMessage: string;
@Input() chipFamilyId: number = 11223;
chipFamilies: IChipFamily[];
constructor(private _adminService: ChipFamilyService) {
}
ngOnInit(): void {
//Initially load 11223 on load
this._adminService.getChipFamily(this.chipFamilyId).subscribe(
chipFamilies => this.chipFamilies = chipFamilies,
error => this.errorMessage = <any>error
);
}
ngOnChanges(changes:{[propKey: string]: SimpleChange}) {
debugger;
this._adminService.getChipFamily(this.chipFamilyId).subscribe(
chipFamilies => this.chipFamilies = chipFamilies,
error => this.errorMessage = <any>error
);
}
}
根据 Harry_Ninh 的极好建议,这是我想出的允许组件之间通信而不使用 @Input 和任何组件选择器的方法:
在我的服务中,我添加了一个主题以允许家长宣布已进行搜索:
@Injectable()
export class ChipFamilyService {
private searchStringSubject = new Subject<string>();
private _searchUrl = 'http://localhost:8888/chipfamily/';
constructor(private _http: Http) {
}
searchAnnounced$ = this.searchStringSubject.asObservable();
announceSearch(searchValue: string) {
this.searchStringSubject.next(searchValue);
}
在我的父组件中,我只是在从我的 typeahead 字段中选择结果后才发布公告:
public onSelectSearchValue(e: TypeaheadMatch): void {
this.chipFamilyService.announceSearch(e.item.id);
}
在我的子组件中,我订阅了公告,然后根据构造函数中的新数据更新模型:
@Component({
template: require('./chip-family.component.html')
})
export class ChipFamilyComponent implements OnInit {
errorMessage: string;
chipFamilyId: number = 11223;
chipFamilies: IChipFamily[];
private gridOptions:GridOptions;
subscription: Subscription;
constructor(private chipFamilyService: ChipFamilyService) {
this.subscription = chipFamilyService.searchAnnounced$.subscribe(
chipFamilyId => {
this.chipFamilyId = Number(chipFamilyId);
this.chipFamilyService.getChipFamily(this.chipFamilyId).subscribe(
chipFamilies => this.chipFamilies = chipFamilies,
error => this.errorMessage = <any>error
);
});
}
这实现了基于预输入搜索使用新数据更新视图面板的预期结果。