Угловая связь между родительскими и дочерними компонентами

У меня есть случай, когда у меня есть родительский компонент и 2 дочерних компонента (компоненты выбора на основе ng-select) Идея состоит в том, что когда я выбираю элемент и в первом ng-select, то же самое должно быть отключено во втором. Наоборот.

В родительском элементе я использую @ViewChildren для запроса компонента и отключенного свойства ввода.

В дочерних элементах я отправляю нужную мне информацию в родительском элементе, когда выбираю и добавляю элемент в ng-select

В этом методе я затем нахожу правильный дочерний компонент и устанавливаю отключенное свойство ввода.

const connectionSelector = this.connectionSelectors.find(connectionSelector => connectionSelector.source == false);
connectionSelector.disabledConnection = this.selectedSourceConnection;

В дочернем компоненте у меня есть метод ngOnChanges для проверки изменений, но свойство disabledConnection не обновляется

Это работает только тогда, когда я загружаю страницу, я одновременно отправляю изменения в родительский элемент в OnInit и когда я меняю элемент в ng-select, поэтому изменения отправляются в родительский

Родительский вид:

<sc-connection-selector [default]="false" [source]="true" [quick]="false"
      [selectedConnection]="selectedSourceConnection"
      [disabledConnectionId]="disabledTargetConnectionId"
      (dataToEmit)="onValueChanged($event)">
</sc-connection-selector>

Ребенок:

<ng-select [items]="connections" bindLabel="userName"
    [placeholder]="'general.select-placeholder' | translate " 
    (change)="onConnectionChange()" 
    groupBy="type"
    dropdownPosition="bottom" 
    [(ngModel)]="selectedConnection">
    <ng-template ng-optgroup-tmp let-item="item">
      <b>{{item.type || 'Unnamed group'}}</b>
    </ng-template>
  </ng-select>

Что мне здесь не хватает?

-Jani


person jani_r    schedule 29.11.2020    source источник
comment
Пожалуйста, поделитесь также файлами parent-component.ts и child-component.ts. Трудно понять, чего именно вы хотите.   -  person T. van den Berg    schedule 30.11.2020


Ответы (1)


Редактировать:

Вы обновляете значение дочернего компонента, а не родительского, OnChanges сработает, если

привязанное к данным свойство директивы изменяется

это означает, что при изменении значения родительского компонента запускается OnChanges для дочернего компонента.

Чтобы получить желаемое поведение, вы должны переместить соответствующий раздел (где вы обновляете свойство disabled) из функции OnChanges в установщик disabledConnectionId, чтобы каждый раз, когда изменяется (disabledConnectionId), вы обновляете раскрывающийся список, вот соответствующий код:

private currentDisabledConnectionId: Number;
@Input()
set disabledConnectionId(val: number) {
  if (this.currentDisabledConnectionId !== val) {
    this.currentDisabledConnectionId = val;
    this.setDisabledFields();
  }
}

private setDisabledFields() {
  this.connections.find(
    connection => connection.id == this.currentDisabledConnectionId
  ).disabled = true;
  console.log("connections: ", this.connections);
}

Обратите внимание, что я изменил ввод на сеттер и сохранил свойство как частное поле.

Также обратите внимание, что то, что вы разместили на stackblitz, не удаляет предыдущие отключенные поля, а только добавляет новые (я подозреваю, что это потому, что вы только вставили воспроизводимый пример).

Вот рабочий пример разветвления на stackBlitz

person Moshezauros    schedule 29.11.2020
comment
Я попытался создать новый объект с Object.assign, но он не работает. Я также попытался изменить Input на число, это в основном все, что мне нужно, чтобы знать, какой элемент отключить, но это тоже не работает. Если обновить поле из родительского элемента, запросив ViewChildren и установив поле, это работает только при загрузке страницы. Однако, если я установил в родительском поле поле (которое затем передается дочернему элементу), оно работает, но проблема в том, что в child, когда я отключаю элемент, для которого ng-select должен быть отключен. Они используют тот же список предметов. - person jani_r; 30.11.2020
comment
пожалуйста, добавьте html-часть к вашему вопросу - person Moshezauros; 30.11.2020
comment
Затем в дочернем компоненте я нахожу элемент, отправленный от родительского элемента, и отключаю его в списке, например: this.connections.find (connection = ›connection.id == changes ['disabledConnectionId']. CurrentValue) .disabled = правда - person jani_r; 30.11.2020
comment
Готово, может я что не так делаю .... - person jani_r; 30.11.2020
comment
как вы передаете объект connectionSelector от родителя к потомкам? - person Moshezauros; 30.11.2020
comment
Вы заметили, что disabledConnection (то, что вы разместили для первой функции) отличается от disabledTargetConnectionId, который вы передаете дочернему компоненту? - person Moshezauros; 30.11.2020
comment
Я не передаю это от родителей к ребенку. Это список ViewChildren селектора подключения. Есть 2, источник и цель. Я запрашиваю у родителей - person jani_r; 30.11.2020
comment
Свойство дочернего компонента теперь называется disabledConnectionId, а затем в родительском я установил для него disabledTargetConnectionId в исходном соединителе, а в целевом я установил disabledSourceConnectionId. Я знаю, какой из них отключить, прежде чем отправлять весь объект, но мне нужен только идентификатор - person jani_r; 30.11.2020
comment
Хорошо, я не могу помочь, не увидев весь код (а может быть, даже тогда), если бы вы могли воссоздать на stackblitz, было бы лучше - person Moshezauros; 30.11.2020
comment
Вот stackblitz, stackblitz.com / edit / angular-ivy-fwxqqs? file = src / app /. По какой-то причине я не могу применить стили ng-select. Установлено свойство disabled в объекте подключения, но оно не отражается в ng-select. Может, из-за стилей. Однако это работает в моем местном проекте. Может, я ошибся. Проблема в том, что в компонентах у меня только 1 список подключений, но он должен быть разным для источника и цели, поскольку отключенное соединение может быть другим. Может, мне тоже нужно передать это? - person jani_r; 01.12.2020
comment
@jani_r см. обновленный ответ - person Moshezauros; 03.12.2020
comment
Спасибо, миллион, теперь это работает - person jani_r; 03.12.2020
comment
Вам также необходимо сделать это, чтобы ng-select обновлял элементы (упомянутые в документации): _ 1_ - person jani_r; 03.12.2020