Как вызвать ng-шаблон по переменной? - PullRequest
0 голосов
/ 21 июня 2019

Я проверил: ViewChildren для ng-шаблона а также Доступ к нескольким детям с помощью @ viewchild

Но я не могу вызвать свой шаблон через значение переменной ...

Итак, мой шаблон выглядит так:

<ng-container *ngFor="let feature of Object.values(features)">
  <ng-container *ngTemplateOutlet="templates[feature]"></ng-container>
</ng-container>

<ng-template #myFeature>
  Nothing to see here
</ng-template>

<ng-template #myOtherFeature>
  Nothing to see here
</ng-template>

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

export class SomeClass {
   @ViewChildren(TemplateRef) templates: QueryList<TemplateRef<any>>;
}

Итак, идея в том, что я подумал, что смогу сослаться на правильный шаблон, выполнив templates[feature], который должен дать что-то вроде templates['myFeature'] и дать мне правильный шаблон ... но это не так.

Как мне заархивировать это?

Ответы [ 2 ]

0 голосов
/ 21 июня 2019

После некоторого возни внутри ngAfterViewInit, я начал работать так, как я хочу.Это немного уродливо, потому что мне нужно использовать setTimeout и мне нужно поиграть с внутренними переменными (не уверен, что это хорошая идея) ...

Вот stackblitz демонстрация динамического выбора шаблона и рендеринг по значению переменной.

В двух словах, вот как я это сделал, вам нужно 3 вещи:

// to grab all the templates
@ViewChildren(TemplateRef) templates: QueryList<TemplateRef<any>>;
// to be use for template selection
templateMap: { [key: string]: TemplateRef<any> } = {};
// to avoid rendering during the first run when templateMap is not yet ready
templateMapReady = false;

Затем в ngAfterViewInitвы делаете следующее, чтобы построить templateMap:

ngAfterViewInit(): void {
  // setTimeout to bypass the ExpressionChangedAfterItHasBeenCheckedError
  setTimeout(() => {
    // loop through the fetched template
    this.templates.toArray().forEach(t => {
      // for those ng-template that has a #name, they will have references
      const keys = Object.keys((t as any)._def.references);
      if (keys.length === 1) {
        // so we put these in the templateMap
        this.templateMap[keys[0]] = t;
      }
    });
    // now we change it to ready, so it would render it
    this.templateMapReady = true;
  });
}
0 голосов
/ 21 июня 2019

Поскольку вы создали разные шаблоны (разные переменные шаблона), вам необходимо создать разные дочерние представления для каждого из них. ViewChildren будет работать, только если они имеют одну и ту же переменную ссылки на шаблон. И использование в вашем коде будет извлекать каждый экземпляр шаблона, потому что вы передаете TemplateRef, он выбирает каждый экземпляр этого типа.

Я создал стек, который демонстрирует this .

Также обратите внимание, что ваш экземпляр шаблона будет доступен только на ngAfterViewInit(), до тех пор он не будет определен.

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