Angular2 - ссылка на шаблон внутри NgSwitch

У меня есть шаблон NgSwitch. В NgSwitch я хочу получить ссылку на шаблон для инициализированного шаблона. Что-то вроде этого:

    <div class="container" [ngSwitch]="model.type">
        <first-component #ref *ngSwitchCase="0"></first-component>
        <second-component #ref *ngSwitchCase="1"></second-component>
        <third-component #ref *ngSwitchCase="2"></third-component>
    </div>

При нажатии на кнопку в компоненте я хочу вызвать инициализированный компонент (первый / второй / третий) к методу (который определен на интерфейсе, который реализуют все эти 3 компонента). Проблема в том, что ViewChild не определен. Если я переместу #ref в контейнер div, вот так:

<div class="container" #ref [ngSwitch]="model.type">
    <first-component *ngSwitchCase="0"></first-component>
    <second-component *ngSwitchCase="1"></second-component>
    <third-component *ngSwitchCase="2"></third-component>
</div>

ViewChild (ссылка на шаблон) инициализируется, но затем я могу вызвать метод компонента.

Как я могу использовать директиву NgSwitch и переменную ссылки на шаблон? Или, с другой стороны, как я могу вызвать инициализированный компонент из его родителя (в случае, если я перемещаю #ref в контейнер div).

3 ответа

Это работает, если вы используете переменную ссылки на шаблон в ngSwitchCase, сюда:

<div class="container" [ngSwitch]="model.type">
    <first-component #ref *ngSwitchCase="0"></first-component>
    <second-component #ref *ngSwitchCase="1"></second-component>
    <third-component #ref *ngSwitchCase="2"></third-component>
</div>

Обратите внимание, что если у вас есть:

export class SomeComponent {

  @ViewChild('ref') ref;
...

затем ref еще не установлено при вызове конструктора. Даже на init. Только после просмотра init.

Таким образом, со следующим компонентом:

export class AppComponent implements OnInit, AfterViewInit {
  model = {type: 0};

  @ViewChild('ref') ref;

  constructor() {
    console.log('constructor:', this.ref);
  }
  ngOnInit() {
    console.log('ngOnInit:', this.ref);
  }
  ngAfterViewInit() {
    console.log('AfterViewInit:', this.ref);
  }

}

Выход:

constructor: undefined
ngOnInit: undefined
AfterViewInit: FirstComponent {...}

Смотрите демо плункер здесь.

Ссылочная переменная шаблона не должна работать со структурной директивой. Вот объясненная причина: блог Томаса Хильцендегена

Мое решение состоит в том, чтобы создать переменную ссылки на шаблон для тега контейнера, в котором используется [ngSwitch], а затем получить доступ к его дочернему элементу, используя его дочернее свойство. Например

<div [ngSwitch]="..." [class.error] = "(elem.children.item(0).className.indexOf('someClass') !== -1" #elem> 
... 
</div>

Также вы можете использовать forwardRef без каких-либо ссылок на шаблоны, как показано ниже:

@Component({
    ...
    selector: 'first-component',
    providers: [{
        provide: BaseEnumeratedComponent,
        useExisting: forwardRef(() => FirstComponent)
    }]
})

И доступ к списку компонентов, которые используют switch-case, используя ngAfterViewInit() в родительском компоненте. Или, если вы хотите получить доступ к определенному использованию provide: FirstComponent

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