我有两个组件,app.component和encours.component,我的app.component的导航栏中有一个选择,需要在每次更改时向encours.component发送值。第一次我可以得到价值,但是之后我什么也得不到。我有一个名为dataService的通信服务,并且我使用路由器出口进行路由,因此无法传递来自router-outlet标签的数据 我试图在encours.component中实现ngOnChange方法,但是它不起作用。
这是我的服务代码:
@Injectable()
export class DataService{
private serviceSource = new BehaviorSubject(3);
currentService = this.serviceSource.asObservable();
constructor(){}
changeService(service: number){
this.serviceSource.next(service);
}
}
这是我的app.component.html代码:
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">SAFRAN</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
<form class="form-inline my-2 my-lg-0" *ngIf="showSelect">
<select class="custom-select" id="service" #serviceSelect [(ngModel)]="service" name="service" (change)="setSelection(serviceSelect.value)">
<option *ngFor = "let service of listeServices" value="{{service.id}}">{{service.nom}}</option>
</select>
</form>
</nav>
<router-outlet>
</router-outlet>
这是我的app.component.ts代码:
export class AppComponent implements OnInit{
public listeServices: any;
service: number;
constructor(private router:Router, private serviceServ : ServiceService, private data : DataService) {
router.events.forEach((event) => {
if(event instanceof NavigationStart) {
//I get some data from an API
this.getServices();
//I show the select only if the route is encours
this.showSelect = event.url === "/encours";
}
});
}
ngOnInit(): void {
this.data.currentService.subscribe(service => this.service = service)
}
public setSelection(selectedValue: any): void {
this.service = selectedValue;
this.data.changeService(selectedValue);
}
这是encours.component.html文件:
<table *ngIf="listeFamilles">
<tbody>
<tr *ngFor="let f of listeFamilles">
<th style="vertical-align: middle; padding-left: 10px;">{{ f.nom }}</th>
<td id="{{f.nom}}" style="vertical-align: top;"></td>
</tr>
</tbody>
</table>
最后,我的encours.component.ts:
export class EncoursComponent implements OnInit, OnChanges{
service : number;
constructor(private serviceFam: FamillesService, private serviceOpe: OperationsService, private serviceVar: VarianteService, private serviceAff: AffaireService, private serviceAffecter: AffecterService, private data : DataService) {
this.data.currentService.subscribe(service => this.service = service);
}
//This function is never called
ngOnChanges(changes: SimpleChanges): void {
console.log(changes);
}
答案 0 :(得分:2)
只要该值发生更改,就会调用您在 encours.component.ts 中对 DataService 的data
字段的订阅,因此该组件实际上是已经收到此数据。对于这样的用例,实现接口ngOnChanges
会很麻烦,因为该组件已经在构造函数中的订阅中接收到更新的值。
在构造函数中更改订阅行以控制台记录此更新:
this.data.currentService.subscribe(service => {
console.log(service);
this.service = service;
});
现在可以看到实际上已经是这种情况了。
如果您想(我认为是冗长的话)解雇onChanges()
并在那里处理更新,则需要进行额外的工作。仅当具有onChanges()
属性的属性发生更改时,@Input
才会触发。这将要求您通过模板通过异步管道实现 DataService 的currentService
的值作为@Input
的模板。
可在以下位置找到实现此目标的示例:https://www.concretepage.com/angular-2/angular-2-4-onchanges-simplechanges-example。这里的官方文档:https://angular.io/api/core/OnChanges。
答案 1 :(得分:0)
// This function is never called
ngOnChanges(changes: SimpleChanges): void {
console.log(changes);
}
当然,当任何数据绑定属性发生更改时,就会调用ngOnChanges挂钩, 因此,如果它仅在组件 EncoursComponent 具有 @Input 属性的情况下起作用。