为什么Angular不赞成使用旧的“替换”指令选项?

时间:2019-04-05 16:46:23

标签: angular

在旧的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团队删除了这些功能?而且有什么解决方案可以做到吗?

1 个答案:

答案 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