передача динамических данных дочернему компоненту

#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>
 

Надеюсь, это решит вашу проблему.