带有选择器的ng-content中的条件复制templateref

时间:2018-04-28 07:12:30

标签: angular angular-template ng-content

我有一个组件可根据客户端设备大小切换组件的模板。组件代码是:

import {Component} from '@angular/core';
import {BreakpointObserver, Breakpoints} from '@angular/cdk/layout';

@Component({
    selector: 'ui-switcher',
    template: `
        <ng-content *ngIf="isSmall" select="mobile"></ng-content>
        <ng-content *ngIf="!isSmall" select="web"></ng-content>
`
})
export class UiSwitcherComponent {
    public isSmall: boolean;

    constructor(breakpointObserver: BreakpointObserver) {
        breakpointObserver.observe([Breakpoints.Small, Breakpoints.XSmall]).subscribe(result => {
            this.isSmall = result.matches;
        });
    }    
}

我这样用:

<ui-switcher>
    <web>
        <!-- some commented details -->
        <input class="form-control mr-2" #searchInput 
        type="text" (keyup)="this.search(searchInput.value)">
    </web>

    <mobile>
        <!-- some commented details -->
        <input class="form-control" #searchInput 
        type="text" (keyup)="this.search(searchInput.value)">
    </mobile>
</ui-switcher>

在移动设备尺寸中,一切正常,但在桌面尺寸中,传递给search(value)功能的值始终为空字符串。

当我调试应用程序时,似乎#searchInput templateref无法正常工作(它引用的元素的值始终为空)。

为什么templateref无法正常工作?

1 个答案:

答案 0 :(得分:3)

在角度模板中,每个视图的参考变量应该是唯一的。

视图可以是两种类型查看 EmbeddedView 。我们在结构指令(ng-template标签或*ngFor内)中编写的模板表示嵌入式视图。这样,我们可以在不同的ng-templates中使用相同名称的模板引用变量。

有关示例,请参阅

我们假设我们有AppComponent并在模板中写道:

<ui-switcher>
    <web>
        <!-- some commented details -->
        <input class="form-control mr-2" #searchInput 
        type="text" (keyup)="this.search(searchInput.value)">
    </web>

    <mobile>
        <!-- some commented details -->
        <input class="form-control" #searchInput 
        type="text" (keyup)="this.search(searchInput.value)">
    </mobile>
</ui-switcher>

Angular将其视为一个AppComponentView,因为此模板中没有任何结构指令。两个输入属于同一视图。

现在,当Angular编译器解析此模板时,它会为每个具有ViewBuilder属性的视图创建一个refNodeIndices

private refNodeIndices: {[refName: string]: number} = Object.create(null);

包含当前模板中的所有引用。

让我们重现您的案例: enter image description here

我们可以看到第二个模板引用变量覆盖了之前的。

结果Angular处理同一元素上的click事件:

enter image description here