Ответ 1
Используйте @Input
для передачи ваших данных дочерним компонентам, а затем используйте ngOnChanges
(https://angular.io/api/core/OnChanges), чтобы увидеть, изменился ли этот @Input
на лету.
У меня есть MasterComponent, который загружает заголовок, нижний колонтитул, боковую панель и т.д. В заголовке есть раскрывающийся список, параметры которого устанавливаются после входа пользователя в систему. Я хочу, чтобы заголовок был постоянным, даже если я перемещаюсь по разным маршрутам, в которых загружаются разные дочерние компоненты., Означает, что выбранный параметр не должен изменяться и значение раскрывающегося списка должно быть доступно во всех дочерних компонентах. При изменении значения раскрывающегося списка текущий дочерний компонент должен быть обновлен/перезагружен.
Как мне подойти к этой проблеме? Я хочу, чтобы событие-слушатель было функциональным. Как только модель из MasterComponent изменится, перезагрузите текущий дочерний компонент. При обновлении переменной MasterComponent переменная ChildComponent будет прослушивать обновление и запускать некоторую функцию или снова вызывать некоторый API и перезагружать ChildComponent.
// routes
const appRoutes: Routes = [
{
path: '',
redirectTo: 'login',
pathMatch: 'full',
},
{ path: 'login', component: LoginComponent },
{ path: 'logout', component: LogoutComponent },
{
path: '',
component: MasterComponent,
canActivate: [AuthGuard],
children: [
{ path: 'record/create', component: RecordCreateComponent }, // create record for selectedRestaurant in MasterComponent
{ path: 'record/', component: RecordComponent }, // shows all record of current selectedRestaurant in MasterComponent
{ path: 'record/:id/update', component:RecordUpdateComponent }, // show form to edit record having id
{ path: 'record/:id', component: RecordComponent }, // show record details having id
]
},
{ path: '**', redirectTo: 'login' }
];
// MasterComponent
@Component({
selector: 'master',
templateUrl: templateUrl,
styleUrls:[styleUrl1]
})
export class MasterComponent implements AfterViewInit, OnInit{
restaurants: Array<Restaurant> = [];
user:User;
selectedRestaurant: Restaurant;
constructor(private router: Router, private storageHelper:StorageHelper){
}
ngAfterViewInit() {
}
ngOnInit(){
this.user = JSON.parse(this.storageHelper.getItem('user'));
this.restaurants = this.user.restaurants;
this.selectedRestaurant = this.restaurants[0];
this.router.navigate(['/record/' + this.selectedRestaurant.id]);
}
onRestaurantChange(){
this.router.navigate(['/record/' + this.selectedRestaurant.id]);
}
createRecord(){
}
}
Используйте @Input
для передачи ваших данных дочерним компонентам, а затем используйте ngOnChanges
(https://angular.io/api/core/OnChanges), чтобы увидеть, изменился ли этот @Input
на лету.
В Angular для обновления компонента, включая его шаблон, есть прямое решение этого вопроса, имеющее свойство @Input
в вашем ChildComponent и добавленное в ваш @Component
декоратор changeDetection: ChangeDetectionStrategy.OnPush
следующим образом:
import { ChangeDetectionStrategy } from '@angular/core';
@Component({
selector: 'master',
templateUrl: templateUrl,
styleUrls:[styleUrl1],
changeDetection: ChangeDetectionStrategy.OnPush
})
export class ChildComponent{
@Input() data: MyData;
}
Это выполнит всю работу по проверке изменения входных данных и выполнению повторной визуализации компонента.
обновление @Vladimir Tolstikov ответа
Создайте дочерний компонент, который использует ngOnChanges
.
ChildComponent.ts ::
import { Component, OnChanges, Input } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'child',
templateUrl: 'child.component.html',
})
export class ChildComponent implements OnChanges {
@Input() child_id;
constructor(private route: ActivatedRoute) { }
ngOnChanges() {
// create header using child_id
console.log(this.child_id);
}
}
теперь используйте его в шаблоне MasterComponent и передавайте данные в ChildComponent, например:
<child [child_id]="child_id"></child>
Вы можете использовать @input с ngOnChanges, чтобы увидеть изменения, когда они произошли.
ссылка: https://angular.io/api/core/OnChanges
(Или)
Если вы хотите передавать данные между несколькими компонентами или маршрутами, тогда используйте Rxjs.
Service.ts
import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class MessageService {
private subject = new Subject<any>();
sendMessage(message: string) {
this.subject.next({ text: message });
}
clearMessages() {
this.subject.next();
}
getMessage(): Observable<any> {
return this.subject.asObservable();
}
}
Component.ts
import { Component, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { MessageService } from './_services/index';
@Component({
selector: 'app',
templateUrl: 'app.component.html'
})
export class AppComponent implements OnDestroy {
messages: any[] = [];
subscription: Subscription;
constructor(private messageService: MessageService) {
// subscribe to home component messages
this.subscription = this.messageService.getMessage().subscribe(message => {
if (message) {
this.messages.push(message);
} else {
// clear messages when empty message received
this.messages = [];
}
});
}
ngOnDestroy() {
// unsubscribe to ensure no memory leaks
this.subscription.unsubscribe();
}
}