我正在研究如何在Angular Material中实现Menu。
In their example,他们将模板变量#menu
分配给matMenu
matMenu
是exportAs
组件中的mat-menu
<button mat-button [matMenuTriggerFor]="menu">Menu</button>
<mat-menu #menu="matMenu">
<button mat-menu-item>Item 1</button>
<button mat-menu-item>Item 2</button>
</mat-menu>
我想知道,如果我删除分配并保留模板变量,会不会一样?
<button mat-button [matMenuTriggerFor]="menu">Menu</button>
<mat-menu #menu>
<button mat-menu-item>Item 1</button>
<button mat-menu-item>Item 2</button>
</mat-menu>
在StackBlitz上进行了测试,它的工作原理相同。
答案 0 :(得分:1)
可以,但是使用exportAs
方法是一种惯例,因为您可以在一个元素上使用多个指令,并且该元素本身可以是一个组件。使用模板变量将不清楚该变量应设置为什么。这就是为什么他们引入 exportAs
因此,基本上,通过一个简单的示例,您可以使用未分配的模板变量,但是要注意一些错误,如果其他开发人员决定在{{1 }}标签:)
因此,我做了一些挖掘,发现自己错了,并做了一些example stack。如果您有此模板:
mat-menu
并且<div #test1></div>
<hello #test2></hello>
<hello hi #test3></hello>
<hello hi foo #test4></hello>
<div hi #test5></div>
<div hi foo #test6></div>
是一个组件,而hello
和hi
是伪指令,模板引用将是:
foo
因此,这基本上意味着,如果不对模板变量使用赋值,它将始终选择元素。如果此元素是组件,则将获取组件实例。不使用赋值表示法就无法获得指令。因此,不可能有像我以前认为的那样发生可变冲突。
作为旁注,与您的问题并不完全相关。如果在这些元素上使用#test1 => HTMLDivElement
#test2 => HelloComponent
#test3 => HelloComponent
#test4 => HelloComponent
#test5 => HTMLDivElement
#test6 => HTMLDivElement
,将得到相同的结果。区别在于您不会得到@ViewChild('testx')
,而是得到HTMLElement
,其中ElementRef
指向.nativeElement
。如果要访问绑定到此元素的任何指令,则需要使用HTMLElement
属性:
read
因此,最重要的是,在角材料世界中,始终使用@ViewChild('test6', { read: FooDirective })
test6?: FooDirective;
模板分配是惯例,即使这对于组件而言不是必需的。但是我想它可以提高代码的可读性和一致性。
另一个原因可能是,如果您开始对模板代码进行单元测试,则需要为模板引用分配所引用的组件/指令提供一个模拟。如果仅使用模板变量,则不会出现错误。因此,我想您可以更好地测试模板,因为它会提供您必须模拟的反馈,从而测试该实现