#javascript #angular #typescript #rxjs
Вопрос:
У меня есть дочерний компонент в качестве
export class AlertComponent implements OnInit {
@Input() messageData: string | string[];
constructor() { }
ngOnInit(): void {
}
}
У меня есть родительский компонент, в котором в шаблоне я использую вышеуказанный компонент
<app-alert *ngIf="!!alertsCount" [type]="'danger'"
[messageData]="alertMessageData"></app-alert>
<mat-select class="select--width--130" (selectionChange)="changeAlertType($event)" [(value)]="alertType" placeholder="Alert Types">
<mat-option *ngFor="let alertType of alertTypes" [value]="alertType.name">
{{ alertType.name }}
</mat-option>
</mat-select>
в родительском компоненте ts
getAlertMessageData(alertType: string) {
switch (alertType) {
case 'firing':
case 'silenced':
case 'resolved':
this.alertMessageData = `There are ${this.alertsCount} ${alertType} alerts`;
break;
case 'all':
this.alertMessageData = `There are ${this.alertsCount} alerts`;
break;
}
console.log(this.alertMessageData);
}
changeAlertType(event: MatSelectChange) {
this.alertType = event.value;
this.getAlertMessageData(event.value);}
Однако данные сообщения не обновляются при изменении выбора типа предупреждения, как передать данные сообщения, чтобы они обновлялись после изменения выбора мата?
Комментарии:
1. Откуда вы знаете, что он не обновляется?
2. Вы передаете
[type]="'danger'"
, но я не вижуInput() type
в вашем дочернем компоненте такжеchangeAlertType()
метода, который вы вызываетеgetAlertMessageData()
, не передавая тип предупреждения, что метод ожидает param, хотя разве он не выдает ошибку?3. При изменении его данные сообщения не обновляются в шаблоне родителя и совпадают с данными по умолчанию.
4. @KamranKhatti извините, что я пропустил этот параметр, когда набирал вопрос. у ребенка есть тип @Input ().
5. @BizzyBob я понимаю, но, как я уже сказал, это утешает. регистрирует правильное сообщение, но не показывает правильное сообщение в шаблоне, и я предполагаю, что требуется значение по умолчанию, но не та часть проблемы, на которой мне нужно сосредоточиться
Ответ №1:
Что я вижу из кода, так это то, что вы передаете строку или массив строк. При передаче строки вы можете обнаружить изменения с помощью ngOnChanges
при условии, что вы можете правильно отправлять данные из родительского компонента.
Когда вы передаете массив, вам необходимо изменить ссылку, так как массив является объектом и будет передан по ссылке, и обнаружение угловых изменений не обнаружит никаких изменений в нем, даже если вы используете ngOnChanges
.
При использовании ngOnchanges
вы можете использовать set property @Input
, установить свойство и запустить определение изменений.
export class ChildComponent implements OnChanges {
@Input() set messageData: any = [];
ngOnChanges(changes) {
// code here
// make changes here
}
}
Я предлагаю вам прочитать это. Как работает обнаружение изменений?
Комментарии:
1. Спасибо за ответ, но ngOnChanges мне нужно избегать, потому что это не очень хорошая практика. То, что я ищу, — это какой-то ответ, связанный с наблюдаемым.
2. Можете ли вы поделиться ссылкой, которая предполагает это? Это зависит от необходимости, если вы не хотите его использовать. Вы можете использовать наблюдаемые объекты rxjs, передающие обновленные значения и добавляющие их в представление с помощью асинхронного канала. Не нужно беспокоиться об обнаружении изменений, они будут автоматически обновляться при просмотре.
3. @Apporva Я поделюсь ссылкой, можете ли вы подсказать, как это можно сделать с помощью наблюдаемых rxjs и асинхронного канала?
4. Кроме того, вы должны проверить это , и если вы беспокоитесь о производительности, то вам следует использовать стратегию OnPush вместо стратегии по умолчанию.
5. Да, я могу поделиться ссылкой, но вам, возможно, потребуется изменить стратегию обнаружения изменений, я добавил одну ссылку в ответ, чтобы пройти через это. Проблема, с которой вы столкнулись, связана с обнаружением изменений и способом передачи данных ребенку.
Ответ №2:
Попробуйте использовать Наблюдаемые
messageSubject = new BehaviorSubject('');
alertMessage$ = this.messageSubject.asObservable();
// In your switch statement
this.messageSubject.next(`There are ${this.alertsCount} ${alertType} alerts`);
// Передайте наблюдаемый в дочернем компоненте в качестве входных данных
<app-alert [messageData]="alertMessage$ | async"></app-alert>
Надеюсь, это решит вашу проблему.