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