在旧的Angular 1.x中,我们可以构建指令并具有设置“替换”的选项:在配置中为true,这将允许您告诉Angular用指令所组成的内容替换整个DOM元素。 / p>
我对Angular 2+还是很陌生,但是到目前为止,我们似乎只有2种选择以相同的方式构建组件:
1)像这样<app-my-component></app-my-component>
2)像这样<div app-my-component></div>
问题是我发现这两个问题都存在:
使用方法#1可能会破坏CSS样式,因为Angular会在页面中放置一个额外的DOM元素,这意味着如果您有一个包含<ul>
和子<li>
元素的HTML结构,而您想要要将<li>
元素设为可重用的组件,则最终的DOM如下所示:
<ul>
<app-my-component>
<li>Inner</li>
</app-my-component>
</ul>
这将有效地破坏所有以ul > li
为目标的CSS。
使用方法2,我们可以解决CSS样式问题,但是删除了组件应该提供的抽象,因为该组件的使用者现在必须了解所需的元素类型:
<ul>
<li app-my-component>
Inner
</li>
</ul>
在上述情况下,开发人员必须知道使用<li>
才能使事情正常运行。这是一个非常简单的示例,但是更复杂的场景对于开发人员而言可能不太直观,从而引起头痛。
看看这个例子。由于基础HTML / CSS的性质,我不得不像这样设置这2个(主要/辅助)组件,并使用内部<ng-content>
来正确显示导航。如您所见,必须将<li>
元素粘贴在父<div>
的外观和感觉中,这很奇怪,并增加了开发人员了解底层HTML的需要。
<div app-platform-navigation-primary label="Test" icon="account_box" link="#">
<li app-platform-navigation-secondary label="Test2" link="#"></li>
<li app-platform-navigation-secondary label="Test3" link="#"></li>
<li app-platform-navigation-secondary label="Test4" link="#"></li>
<li app-platform-navigation-secondary label="Test5" link="#"></li>
</div>
摘要
总的来说,这两种方法各有利弊,但是我觉得如果我们仍然可以使用“替换”方法(可以让您使用提供所有抽象的方法#1进行开发),则可以同时兼顾两者。您需要,但不会在页面上添加“额外” DOM元素,以使CSS继续工作。
什么原因导致Angular团队删除了这些功能?而且有什么解决方案可以做到吗?
答案 0 :(得分:3)
当开发人员要使用您的组件时,他们必须查看您的文档以查看选择器的名称。那么,指示开发人员使用<app-my-component>
与<li app-my-component>
有什么区别?请注意,组件选择器支持CSS选择器。换句话说,您可以确保您的组件只能与<li>
主机元素一起使用:
@Component({
selector: 'li[app-my-component]'
...
})
使用所示的严格选择器,在其中指定元素和属性,可以防止开发人员在其预期用途之外使用组件。
对于您的示例用例:
@Component({
selector: 'ul[app-platform-navigation-primary]'
...
})
和..
@Component({
selector: 'li[app-platform-navigation-secondary]'
...
})
组件的主机元素不必是<div>
。它可以是<ul>
,<li>
或其他任何值。
如果您希望抽象出组件内部在使用<ul>
和<li>
的事实,那么请看一下this SO answer。该答案说明了如何将每个子组件包装在父组件的<li>
内。
总而言之,可以实现与AngularJs相同的结果,在AngularJs中,您不需要额外的元素,而无需使用replace
。