Кому принадлежит цикл обновления TemplateRef в угловом дротике? - PullRequest
0 голосов
/ 23 января 2019

У меня проблема с циклом обновления TemplateRef при использовании с ngTemplateOutlet.

Рассмотрим HTML:

           <card [value]="item" full>

            <template #buttons let-obj="obj"> <!-- THE TEMPLATE -->
              <button (click)="myBoolean = false"
                *ngIf="myBoolean">  <!-- THIS IF -->
               SET FALSE
              </button>

              <button (click)="myBoolean = true"
                *ngIf="!myBoolean"> <!-- THIS IF --> 
               SET TRUE
              </button>
            </template>

           </card>

           <button (click)="myBoolean = !myBoolean">TOGGLE</button>

Итак, у компонента страницы есть карточка.У карты есть это свойство:

  @ContentChild('buttons')
  TemplateRef buttons; 

Кнопки TemplateRef используются этим кодом:

<template [ngTemplateOutlet]="buttons"
     [ngTemplateOutletContext]="{ 'obj': value }"></template>

Хорошо работает, и кнопка отображается на основе переменной myBoolean компонента страницы.Кроме того, когда вы нажимаете кнопки внутри <template>, цикл работает, и они меняются в зависимости от переменной myBoolean.

Проблема заключается в том, что переменная myBoolean изменяется чем-то за пределами <template>.В приведенном выше примере HTML, когда я нажимаю кнопку TOGGLE, переменная myBoolean изменяется, однако <template> не обновляется соответствующим образом.

Итак, кому принадлежит обновление TemplateRef?
Что я могу сделать, чтобызаставить его обновиться правильно?

1 Ответ

0 голосов
/ 24 января 2019

Представление, в котором создается экземпляр TemplateRef, имеет право собственности.Поскольку ваши компоненты используют ChangeDetectionStrategy.OnPush, их представления будут обновляться только при срабатывании

  1. обработчика события (например, (event)=handleEvent), привязанного в представлении компонента,
  2. значения ввода (например, <card [input]="value">) изменяется, или
  3. компонент внедрил ChangeDetectorRef и вызвал changeDetector.markForCheck().

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

В вашем примере вы проецируете <template> в представление вашего <card> компонента.Предположительно ваш <card> компонент затем визуализирует это <template> в своем собственном представлении через NgTemplateOutlet.Таким образом, чтобы обновленный <template> обновлялся при изменении myBoolean, компонент <card> должен быть отмечен для проверки.

Причина, по которой представление обновляется правильно, когда вы нажимаете кнопку внутри <template> по причине (1) выше.Обработчик событий помечает представление, в котором он отображается (<card>), для проверки.

По той же причине он не работает , когда вы нажимаете кнопку TOGGLE в родительском представлении.: это только отмечает родительское представление, которое будет проверено.Поэтому, когда родительское представление обнаруживается в результате пометки для проверки, представление <card> пропускается, поскольку ни одно из трех условий для представления <card> не было выполнено.

Итак, чтобычтобы обновленное <template> обновлялось при нажатии кнопки TOGGLE, вам нужен обработчик, чтобы каким-то образом вызвать markForCheck() для ChangeDetectorRef представления, в котором <template> отображается .

Хорошая новость в том, что это возможно, но, к сожалению, оно не очень чистое.Есть несколько способов сделать это, но вот идея:

Добавьте метод к <card>, чтобы абстрагировать детали использования ChangeDetectorRef:

@Component(...)
class CardComponent {
  CardComponent(this._changeDetector);

  final ChangeDetectorRef _changeDetector;

  void updateButtons() {
    _changeDetector.markForCheck();
  }
}

Запрос для<card> в компоненте вашей страницы и вызов метода обновления при нажатии переключателя:

@Component(...)
class PageComponent {
  @ViewChild(CardComponent)
  CardComponent card;

  void toggle() {
    myBoolean = !myBoolean;
    card.updateButtons();
  }
}
<button (click)="toggle">TOGGLE</button>

Надеюсь, это было полезно, ура!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...