Angular 5:从组件生成 DIV 而不是新标签

Posted

技术标签:

【中文标题】Angular 5:从组件生成 DIV 而不是新标签【英文标题】:Angular 5: generate DIV instead of new tag from component 【发布时间】:2018-08-13 02:29:21 【问题描述】:

我想知道在路由器插座中插入组件时是否有办法告诉 Angular 生成 DIV 而不是新标签。现在,我有这个组件代码:

import  Component, OnInit, ViewEncapsulation  from '@angular/core';

@Component(
  selector: 'app-fwc-***-main',
  templateUrl: './fwc-***-main.component.html',
  styleUrls: ['./fwc-***-main.component.css'],
  encapsulation: ViewEncapsulation.None
)
export class Fwc***MainComponent implements OnInit 

  numbers = new Array(35);

  constructor()  

  ngOnInit() 
  


在最终的 HTML 中呈现到这个:

<router-outlet></router-outlet>
<app-fwc-***-main class="ng-star-inserted"> ... </app-fwc-***-main>

我需要的是生成一个带有一些添加类的 div,所以最终结果将是这样的:

<router-outlet></router-outlet>
<div app-fwc-***-main class="grid-y medium-grid-frame"> ... </div>

注意:我需要添加 grid-ymedium-grid-frame 类,以便应用程序具有正确的布局。这是我要更改此 div 的插入标签的主要原因。

提前致谢,

【问题讨论】:

尽管已经说过,指令是正确的方法 @mast3rd3mon 请创建示例以向我们展示它正在工作 @yurzui 见angular.io/guide/attribute-directives#write-the-directive-code @mast3rd3mon 向我们展示路由器示例。我知道如何创建指令 @yurzui 如果你知道如何创建指令,你为什么要反对他们? 【参考方案1】:

以角度selector may be declared 为以下之一:

element-name:按元素名称选择。 .class:按类名选择。 [attribute]:按属性名选择。 [attribute=value]:按属性名和值选择。 :not(sub_selector):仅当元素与sub_selector 不匹配时才选择。 selector1, selector2:选择 selector1selector2 是否匹配。

因此,当 Angular 编译组件/指令元数据时,它会使用 CssSelector 解析选择器并保留所有已解析的数据,例如:

[
  
    "element": null,
    "classNames": [
      "grid-y",
      "medium-grid-frame"
    ],
    "attrs": [
      "app-fwc-***-main",
      ""
    ],
    "notSelectors": []
  
]

Angular 路由器动态创建组件,因此我们的每个路由组件都将具有主机视图。对于基于从 CssSelector 接收的元数据的主机视图角度编译器prepares 模板:

/** Gets a template string for an element that matches the selector. */
getMatchingElementTemplate(): string 
    const tagName = this.element || 'div';
    const classAttr = this.classNames.length > 0 ? ` class="$this.classNames.join(' ')"` : '';

    let attrs = '';
    for (let i = 0; i < this.attrs.length; i += 2) 
      const attrName = this.attrs[i];
      const attrValue = this.attrs[i + 1] !== '' ? `="$this.attrs[i + 1]"` : '';
      attrs += ` $attrName$attrValue`;
   

   return getHtmlTagDefinition(tagName).isVoid ? `<$tagName$classAttr$attrs/>` :
                                                  `<$tagName$classAttr$attrs></$tagName>`;
 

https://github.com/angular/angular/blob/c8a1a14b87e5907458e8e87021e47f9796cb3257/packages/compiler/src/selector.ts#L91-L105

之后主机模板会是这样的:

<div class="grid-y medium-grid-frame" app-fwc-***-main></div>

所以以下内容应该适合你:

selector: '[app-fwc-***-main].grid-y.medium-grid-frame',

Example

【讨论】:

成功了!拜托,你能发送一个链接到任何解释这种语法的文档吗?非常感谢! @Fel ,请查看我在答案中发布的链接,该链接足以满足组件的每个属性 @yurzui 感谢您的解释!你知道是否有办法根据元素和属性进行选择吗?例如。 nz-content[example]【参考方案2】:

然后将selector从:

selector: 'app-fwc-***-main',

selector: '[app-fwc-***-main]',

然后你可以像&lt;div app-fwc-***-main&gt;&lt;/div&gt;一样使用它

@Component 选择器 - css 选择器,用于在 模板

所以你可以使用任何 CSS 选择器,比如

.app-fwc-***-main // <div class='app-fwc-***-main'></div>
#app-fwc-***-main // <div id='app-fwc-***-main'></div>

更多详情请阅读:Component

【讨论】:

需要使用 @Directive 才能使 app-fwc-***-main 成为 div 上的属性 @mast3rd3mon 你说的是哪个属性? app-fwc-***-main,如果它属于像 &lt;div app-fwc-***-main&gt;...&lt;/div&gt; 这样的 div,它需要是一个指令 @mast3rd3mon ,如果它看起来/使用类似属性并不意味着它应该是直接的。 属性应该是输入/输出,属性(这就是我的意思)应该是指令【参考方案3】:

创建指令而不是组件

<div app-fwc-***-main class="grid-y medium-grid-frame"> ... </div>

在这种情况下 app-fwc-***-main 是指令。您可以创建指令并呈现所需的模板,而不是创建组件。

【讨论】:

为什么会这样? @VivekDoshi 因为app-fwc-***-main 需要作为@Fel 想要的方式使用的指令 不,事情不是这样的,@mast3rd3mon,请阅读***.com/questions/32680244/… 只有一个问题...您将如何使用组件模板? @yurzui 可能了解什么是“@Directive”以及为什么在这种情况下需要它的人

以上是关于Angular 5:从组件生成 DIV 而不是新标签的主要内容,如果未能解决你的问题,请参考以下文章

ngFor 在 Angular 中制作 5 个 div 和 5 个 uls——而不是内部项目

Angular 5 - 将数据存储在服务而不是组件中?

Angular 5:从组件访问元素内部 html 以获取动态生成的元素

如何在应用程序首先加载而不是Angular 5中的appComponent时显示登录组件

Angular 5 - 刷新组件(不是整个页面)

如何将 svg 从文件导入 Angular 5 中的组件?