【发布时间】:2017-09-08 13:22:05
【问题描述】:
更新:
正确的问题可能是:“如何实现我自己的ng-container 版本,以便我可以使用“<my-component ...>...</my-component>”而不是“<ng-container my-directive ...>...</ng-container>”。
我正在使用 Angular 4 开发一个新应用程序。我想用包装器组件构建我的整个应用程序,以便在需要时更换实际组件。这对于简单的控件很容易工作,但对于我们想要分解成单独组件的复杂控件则不行。最好的例子是选项卡,因为要求相当稳定:带有标签的选项卡列表和我们显示/隐藏的内容面板。
ng-bootstrap 可能会使用这样的东西:
<ngb-tabset>
<ngb-tab title="Tab 1">
<ng-template ngbTabContent>...</ng-template>
</ngb-tab>
...
<ngb-tabset>
我们可能还有其他类似的组件:
<div class="my-tab-group">
<ul>
<li>Tab 1</li>
...
</ul>
<div class="my-tab" title="Tab 1">...</div>
...
</div>
此时我不想将我的应用程序绑定到特定的实现,而是想定义自己的标签包装器并像这样在任何地方使用它:
<my-tabs-control>
<my-tab-control title="Tab 1">...</my-tab-control>
...
<my-tabs-control>
然后,如果我需要更改标签的工作方式,它会发生在一个地方。但是,如果我们使用包装器组件,那么 HTML 会被宿主元素标签与所需标签交错而污染,这显然会搞砸事情,例如
<my-tabs-control>
<div class="my-tab-group">
<ul>
<li>Tab 1</li>
...
</ul>
<my-tab-control title="Tab 1">
<div class="my-tab" title="Tab 1">...</div>
</my-tab-control>
...
</div>
<my-tabs-control>
我猜这就是为什么很多人问如何解开/删除 Angular 组件中的宿主元素的原因——这会让这变得非常简单。
通常的答案是使用属性选择器,例如:
Remove the angular2 component's selector tag
How to remove/replace the angular2 component's selector tag from HTML
然而,这意味着我们需要知道使用站点的标签结构,这显然破坏了使用命名良好的包装标签的全部意义。
因此,最后,我应该怎么做呢?由于性能原因,这可能是不可能的吗?我已经开始研究 Renderer2,但还没有找到明显的方法来做我想做的事,我想避免非角度 DOM hack。
【问题讨论】:
-
看起来你想使用 ng-content 使用“嵌入”:scotch.io/tutorials/angular-2-transclusion-using-ng-content 官方角度文档似乎缺少这个:github.com/angular/angular.io/issues/3099
-
我已经大量使用 ng-content 来处理投影内容,但这并不能解决组件本身创建的包装器/容器标签的问题。我们可以使用带有指令而不是组件的 ng-container 来获得我们想要的东西,但这看起来很混乱。我们也许可以使用带有元素选择器的指令而不是默认的属性选择器,然后(也许?)使用 Renderer2/code 来渲染内容。我真正想要的是简单地说“在没有包装器/容器/宿主元素的情况下渲染此组件的内容。遗憾的是,我认为这是不可能的。