如何使用多个选择器定义 Angular 2 组件或指令

Posted

技术标签:

【中文标题】如何使用多个选择器定义 Angular 2 组件或指令【英文标题】:How to define an Angular 2 component or directive with multiple selectors 【发布时间】:2017-01-17 18:03:05 【问题描述】:

目标:

为我的应用程序中的组件和指令提供“同义词”选择器。

动机:

有时组件或指令提供的功能可以以不同的方式考虑,而选择器的名称应有意义地表示或简化对组件或指令如何操作的思考(名称是助记符)。

研究:

指令

我观察到 Material 2 为其MdListMdListItem 指令提供了似乎是多个选择器:

https://github.com/angular/material2/blob/master/src/lib/list/list.ts

@Component(
  moduleId: module.id,
  selector: 'md-list, md-nav-list',
  host: 'role': 'list',
  template: '<ng-content></ng-content>',
  styleUrls: ['list.css'],
  encapsulation: ViewEncapsulation.None
)
export class MdList 

...和...

@Component(
  moduleId: module.id,
  selector: 'md-list-item, a[md-list-item]',
  host: 
    'role': 'listitem',
    '(focus)': '_handleFocus()',
    '(blur)': '_handleBlur()',
  ,
  templateUrl: 'list-item.html',
  encapsulation: ViewEncapsulation.None
)
export class MdListItem implements AfterContentInit 
    ...

来自文档中的 Angular 2 属性指令页面:

https://angular.io/docs/ts/latest/guide/attribute-directives.html

@Directive 需要一个 CSS 选择器来识别模板中的 HTML 与我们的指令相关联。属性的 CSS 选择器是 方括号中的属性名称。我们指令的选择器是[myHighlight]。 Angular 将定位模板中具有名为的属性的所有元素 myHighlight.

链接到以下属性选择器 MDN 页面:

https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors

来自 Angular 2 备忘单页面:

https://angular.io/docs/js/latest/guide/cheatsheet.html


我发现的 Material 2 list.ts CSS 选择器的逗号语法表明这些适用于多种情况 - 我对这些选择器所做的评估是:

    class MdList 适用于 md-listmd-nav-list 元素 class MdListItem 适用于具有md-list-item 属性的md-list-itema 元素

组件

来自 Angular 2 架构概述页面:

https://angular.io/docs/ts/latest/guide/architecture.html

选择器:告诉 Angular 创建和插入实例的 CSS 选择器 该组件在父 HTML 中找到 &lt;hero-list&gt; 标记的位置。为了 例如,如果一个应用的 HTML 包含 &lt;hero-list&gt;&lt;/hero-list&gt;,那么 Angular 在这些标签之间插入HeroListComponent 视图的实例。`

有趣的是,在野外,我还没有遇到任何具有多个选择器的组件示例。

心智模型误解:

当我被介绍给 Angular 2 时,我“懒惰地”将 selectors 解释为应用程序 HTML 中表示的组件或指令的名称。

在我的(有缺陷的)心智模型组件选择器中,只有一种有效定义应用程序特定 HTML 元素的方法。

在我的(错误的)心智模型指令选择器中,只有一种方法可以定义应用程序特定的 HTML 元素属性来修改元素的行为。

完成研究并仔细研究(所有文字)文档后,我开始意识到这里有更强大的东西......

一般问题:

    我在哪里弄错了上述任何地方? 我还缺少组件和指令选择器的哪些其他方面?例如这里有更多的能量可以利用吗?

具体问题:

    组件可以有元素属性选择器吗?如果是这样,行为/效果会是什么? 在哪些情况下您希望指令具有元素选择器? 将指令应用于同义词 CSS 属性的语法是什么?例如将指令应用于任何一组 CSS 属性选择器...

【问题讨论】:

不行吗? 我在这里学习 - Angular 2 似乎没有任何问题 不确定“我在这里学习”是什么意思。你有问题还是没有。这只是一个问题吗?你真的试过了吗? OK - 也​​许有问题 - 我有一个选择器 [vx-top-left], [vx-left-top],它旨在匹配具有 vx-top-leftvx-left-top 属性的元素 - 当我只定义/声明一个属性选择器时它可以工作,但是当我一起定义/声明两者时,Angular 没有找到我期望的元素......我的帖子是保守的,假设我只是不理解(而不是相信有问题使用 Angular 2) 这也是我的猜测...我可能遇到了缓存和/或 IDE 问题,这让我的情况感到困惑(我遇到了一些奇怪的(不确定的)行为)...不过,这很好您能够确认我对它的工作原理的理解现在更加准确......谢谢 【参考方案1】:

我哪里弄错了?

“懒惰”解释选择器

我不知道延迟解释的选择器。

如果在组件模板中找到与选择器或组件匹配的标签,则将其升级为 Angular 组件。 如果使用ViewContainerRef.createComponent()(像路由器一样)动态添加组件,则将匹配选择器的标签添加到DOM并将组件应用于它。

在我的(错误的)心智模型组件选择器中,只有一种有效定义应用程序特定 HTML 元素的方法。

选择器用于将 DOM 元素与组件或指令匹配,以便 Angular 知道 DOM 的哪一部分应该成为组件或指令。

我还缺少组件和指令选择器的哪些其他方面?例如这里有更多的能量可以利用吗?

组件可以有元素属性选择器吗?如果是这样,行为/效果会是什么?

您可以使用自定义标签名称、属性和 CSS 类以及它们的任意组合。您不能使用id 或跨越多个元素的选择器。使用, 分隔的多个选择器可用于将组件添加到其中一个匹配的元素中。 许多 Angulars 内置指令使用选择器列表。

在哪些情况下您希望指令具有元素选择器?

指令和组件一样,只是没有自己的视图。

<my-dropdown>
  <my-item></my-item>
  <my-item></my-item>
  <my-item></my-item>
</my-dropdown>

可以由类似的组件实现

@Component(
  selector: 'my-dropdown',
  template: '<ng-content></ng-content>'
)

@Directive(
  selector: 'my-dropdown',
)

他们会做同样的事情。

将指令应用于同义词 CSS 属性的语法是什么?例如将指令应用于任何一组 CSS 属性选择器...

selector: '[attr1],[attr2],[attr3]'

【讨论】:

以上是关于如何使用多个选择器定义 Angular 2 组件或指令的主要内容,如果未能解决你的问题,请参考以下文章

通过 Angular 2 中的 Input 装饰器使用多个属性

如何在 Angular 子组件选择器之间传递内容

Angular - 使用自定义指令加载多个组件返回未定义

Angular 材料 2:如何区分一个组件中的 2 个或多个可排序表?

Angular- 巧用@component装饰器属性

将 CSS plus 选择器与自定义组件一起使用