Angular6: привязка ввода для пользовательского компонента не обновляется правильно

Первый вопрос о StackOverflow, как интересно!

В настоящее время у меня есть два пользовательских компонента, оба принимают пару входных переменных:

<sod-matrix-table #matrix 
  [entities] = "entities" 
  [pairs] = "pairs" 
  [displayedColumns] = "displayedColumns">
</sod-matrix-table>

и :

<data-table 
  #table 
  [type] = "sodMatrixQuery.targetType" 
  [query] = "sodMatrixQuery" >
</data-table>

При обновлении entities, pairs или columns первого тега все обновляется правильно. Например, когда я обновляю массив displayedColumns в компоненте, который использует тег таблицы матриц, таблица внутри этого компонента обновляется с использованием нужных столбцов. Однако, когда я обновляю sodMatrixQuery в компоненте и нажимаю кнопку поиска, объект query в data-table обновляется некорректно, хотя они связаны вместе.

Пример:

data-table имеет поле query и использует этот запрос для отправки запросов REST на сервер. SODMatrixComponent имеет поле sodMatrixQuery и использует тег data-table, привязывая свое поле к другому полю.

Матрица SOD содержит пары объектов. Когда я выбираю 2 пары и нажимаю кнопку поиска, data-table отправляет запрос REST с 2 парами. Однако, когда я удаляю две пары и снова нажимаю поиск, компонент data-table отправляет еще один запрос REST, снова с двумя парами вместо ни одной. При повторном нажатии кнопки поиска отправляется правильный запрос.

Я отлаживал, и внутри все с парами идет нормально, только привязка данных не обновляется вовремя. Есть мысли по этому поводу?

Обновлено: это код, который происходит при нажатии кнопки:

public search() {
    const tempQuery = new SODMatrixQuery(this.lhsType, this.rhsType, [], this.entities);

    // Only look at elements above the diagonal
    for (let i = 1; i < this.pairs.length; i++) {
        for (let j = 0; j < i; j++ ) {
            const p = this.pairs[i][j];
            if (p.checked) {
                tempQuery.addToxicPair(p);
            }
        }
    }

    if (this.dataTable) {
        this.sodMatrixQuery = tempQuery;
        // this.dataTable.query = tempQuery;
        this.dataTable.loadDataPage();
    }

}

Переменные SODMatrixComponent:

@ViewChild("table")
public dataTable: ElimityDataTableComponent;

public sodMatrixQuery: SODMatrixQuery;

Датируемый компонент:

@Input()
public query: Query;

SODMatrixQuery расширяет Query!

Прокомментированная строка ниже - это исправление, позволяющее напрямую обновить объект запроса, но мне просто любопытно, почему привязка данных не работает.

Какова стратегия обнаружения изменений в ваших компонентах? Вы уже проверяли это: netbasal.com/…?

Agash Thamo. 10.08.2018 10:31

Как вы обновляете sodMatrixQuery?

rinukkusu 10.08.2018 10:36

@AgashThamo. Я действительно не установил конкретную стратегию, так что я думаю, что это по умолчанию? Мне просто странно, что он работает с одним тегом, а не с другим

Bertijn Pauwels 10.08.2018 10:36

@rinukkusu Теперь я обновляю свой пост, добавляя больше кода!

Bertijn Pauwels 10.08.2018 10:38

Должно быть по умолчанию, если вы ничего не расширяете. Если один из @Input является объектом или массивом, Angular не обнаружит изменений, если вы измените значения в объекте или массиве, поскольку он будет сравнивать ссылки, которые останутся прежними. Обновлено: возможно ли создать базовый стек и воссоздать свою проблему?

Agash Thamo. 10.08.2018 10:39

@AgashThamo. В настоящее время на работе отредактировал свой пост, добавив еще немного кода, и это все, что я могу сделать на данный момент.

Bertijn Pauwels 10.08.2018 10:45

Похоже, что обнаружению изменений понадобится время, чтобы передохнуть - привязка данных не может быть обновлена ​​между настройкой члена sodMatrixQuery и вызовом this.dataTable.loadDataPage() - поэтому оно все еще имеет старое значение при первом вызове. После этого будет запущено обнаружение изменений, и при втором вызове оно будет иметь правильные значения.

rinukkusu 10.08.2018 10:47

Хорошо, конечно, не беспокойся. Вы слушаете ngOnChanges и обновляете данные?

Agash Thamo. 10.08.2018 10:48

@AgashThamo. В <sod-matrix-table> я его не использую, и значения обновляются нормально. Поэтому я предположил, что это не нужно в компоненте sod-matrix-component

Bertijn Pauwels 10.08.2018 10:53

Это зависит от того, как отображаются ваши компоненты, не видя вашего полного кода, я не могу придумать другого предложения. См. Ответ @rinukkusu, я в основном делаю обновления в пользовательских компонентах, например.

Agash Thamo. 10.08.2018 11:05
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
3
10
114
1

Ответы 1

Похоже, что обнаружению изменений понадобится время, чтобы передохнуть - привязка данных не может быть обновлена ​​между настройкой члена sodMatrixQuery и вызовом this.dataTable.loadDataPage() - поэтому оно все еще имеет старое значение при первом вызове. После этого будет запущено обнаружение изменений, и при втором вызове оно будет иметь правильные значения.

if (this.dataTable) {
    this.sodMatrixQuery = tempQuery;
    // can't update the bindings here
    this.dataTable.loadDataPage();
}

Итак, глядя на вашу текущую архитектуру, было бы лучше переместить вызов loadDataPage() к компоненту dataTable в ловушку жизненного цикла OnChanges, как сказал Агаш в комментариях.

export class ElimityDataTableComponent implements OnChanges {
  // ...
  ngOnChanges(changes: SimpleChanges) {
    if (changes.query) {
      this.loadDataPage();
    }
  }

Таким образом, каждый раз, когда вы обновляете sodMatrixQuery, он автоматически загружает новые данные.

Другие вопросы по теме