带选择器的ng-content中的条件重复templateref [英] Conditional duplicate templateref in ng-content with selector

查看:127
本文介绍了带选择器的ng-content中的条件重复templateref的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个组件,可以根据客户端设备的大小来切换组件的模板.组件代码为:

I have a component which toggles the component's template based on client device size. Component code is:

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)函数的值始终为空字符串.

In the mobile size, everything works correctly but in desktop size the value passed to search(value) function is always an empty string.

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

When I debug the app, it seems that #searchInput templateref is not working correctly (value of the element it refers to is always empty).

为什么templateref无法正常工作?

Why templateref doesn't work correctly?

推荐答案

在角度模板中,每个视图的引用变量均应唯一.

In angular template reference variables should be unique per view.

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

Views can be two types View and EmbeddedView. Templates, that we write within structural directives(inside ng-template tag or *ngFor), represent embedded views. This way we can have the same name of template reference variable in different ng-templates.

有关示例,请参见

假设我们有AppComponent并用模板编写:

Let's imagine we have AppComponent and wrote in template:

<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 treats it as one AppComponentView because there is no any structural directives in this template. Both inputs belong to the same view.

现在,当Angular编译器解析此模板时,它会创建一个 ViewBuilder noreferrer> refNodeIndices 属性:

Now when Angular compiler parses this template it creates one ViewBuilder per view with refNodeIndices property:

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

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

that holds all references in current template.

让我们复制您的案例:

Let's reproduce your case:

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

We can see that second template reference variable overrides previous.

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

And as result Angular handles click event on the same element:

这篇关于带选择器的ng-content中的条件重复templateref的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆