Angular 中的 @Directive 与 @Component
Posted
技术标签:
【中文标题】Angular 中的 @Directive 与 @Component【英文标题】:@Directive vs @Component in Angular 【发布时间】:2015-12-17 06:27:32 【问题描述】:Angular 中的@Component
和@Directive
有什么区别?
他们两个似乎都在做同样的任务,并且具有相同的属性。
有哪些用例以及何时更喜欢一个而不是另一个?
【问题讨论】:
组件是带有模板的指令,@Component
装饰器实际上是一个@Directive
装饰器扩展了面向模板的特性 - source。
指令 vs 组件是新的服务 vs 工厂。混淆也增加了,因为当实际需要组件定义中的其他组件时,您在 directives
数组中指定它们......也许下面的 Lida Weng 评论有助于澄清组件“它实际上是一个扩展的'指令'”跨度>
组件实际上是扩展指令,它们只需要你有一个模板(html)而不是指令。所以你可以使用指令来修改现有的 html 元素,组件生成 html 元素
【参考方案1】:
@Component 需要视图,而@Directive 不需要。
指令
我将@Directive 比作带有选项 的Angular 1.0 指令(指令不限于属性使用。)指令将行为添加到现有DOM 元素或现有组件实例.指令的一个示例用例是记录对元素的点击。restrict: 'A'
import Directive from '@angular/core';
@Directive(
selector: "[logOnClick]",
hostListeners:
'click': 'onClick()',
,
)
class LogOnClick
constructor()
onClick() console.log('Element clicked!');
这样使用:
<button logOnClick>I log when clicked!</button>
组件
一个组件,而不是添加/修改行为,实际上创建了它自己的视图(DOM 元素的层次结构)和附加的行为。一个示例用例可能是联系人卡片组件:
import Component, View from '@angular/core';
@Component(
selector: 'contact-card',
template: `
<div>
<h1>name</h1>
<p>city</p>
</div>
`
)
class ContactCard
@Input() name: string
@Input() city: string
constructor()
这样使用:
<contact-card [name]="'foo'" [city]="'bar'"></contact-card>
ContactCard
是一个可重用的 UI 组件,我们可以在应用程序的任何位置使用它,甚至在其他组件中。这些基本上构成了我们应用程序的 UI 构建块。
总结
当您想要创建一组可重用的具有自定义行为的 UI DOM 元素时,请编写一个组件。当您想要编写可重用的行为来补充现有的 DOM 元素时,请编写指令。
来源:
@Directive documentation @Component documentation Helpful blog post【讨论】:
@directive 注释是否有模板/模板Url 属性? 这个答案仍然正确吗? angular2 教程本身创建了一个没有视图的组件 它没有视图,但是在组件中必须使用templateurl或template 我喜欢这种答案,但是当框架发生重大变化时,我真的很感激更新。 这个需要稍微改一下。 angular 2 API 发生了变化。不再有 View 装饰器。【参考方案2】:组件
-
要注册组件,我们使用
@Component
元数据注释。
Component 是一个指令,它使用影子 DOM 来创建称为组件的封装视觉行为。组件通常用于创建 UI 小部件。
组件用于将应用程序分解为更小的组件。
每个 DOM 元素只能存在一个组件。
@View
装饰器或 templateurl 模板在组件中是必需的。
指令
-
要注册指令,我们使用
@Directive
元数据注释。
指令用于向现有 DOM 元素添加行为。
指令用于设计可重复使用的组件。
每个 DOM 元素可以使用许多指令。
指令不使用视图。
来源:
https://www.devdiscuss.com/difference-between-component-and-directive-in-angular-2/
【讨论】:
组件 - 第 4 点。我认为它是错误的 - 它可以多次使用。它实际上是一个扩展的“指令” 可以用例子来扩展它。 它并不总是 Shadow Dom 。取决于视图封装【参考方案3】:组件是一个带有模板的指令,@Component
装饰器实际上是一个 @Directive
装饰器扩展了面向模板的特性。
【讨论】:
不知道为什么你被否决了太多。对我来说,@Component 似乎是一个带有模板(用于生成视图)的指令。【参考方案4】:在 Angular 2 及更高版本中,“一切都是组件”。组件是 我们在页面上构建和指定元素和逻辑的主要方式, 通过添加功能的自定义元素和属性 我们现有的组件。
http://learnangular2.com/components/
但是 Angular2+ 中的指令是什么?
属性指令将行为附加到元素。
Angular中有三种指令:
组件 - 带有模板的指令。 结构性指令 - 更改 通过添加和删除 DOM 元素来调整 DOM 布局。 属性指令—更改元素的外观或行为, 组件或其他指令。
https://angular.io/docs/ts/latest/guide/attribute-directives.html
所以在 Angular2 及以上版本中发生的是 指令 是向 元素 和 组件 添加功能的属性。
请看下面来自 Angular.io 的示例:
import Directive, ElementRef, Input from '@angular/core';
@Directive( selector: '[myHighlight]' )
export class HighlightDirective
constructor(el: ElementRef)
el.nativeElement.style.backgroundColor = 'yellow';
那么它的作用是,它会扩展你的组件和 HTML 元素并添加黄色背景,你可以像下面这样使用它:
<p myHighlight>Highlight me!</p>
但组件将创建具有以下所有功能的完整元素:
import Component from '@angular/core';
@Component(
selector: 'my-component',
template: `
<div>Hello my name is name.
<button (click)="sayMyName()">Say my name</button>
</div>
`
)
export class MyComponent
name: string;
constructor()
this.name = 'Alireza'
sayMyName()
console.log('My name is', this.name)
你可以像下面这样使用它:
<my-component></my-component>
当我们在 HTML 中使用标签时,会创建这个组件并调用并渲染构造函数。
【讨论】:
【参考方案5】:变化检测
只有@Component
可以是变更检测树中的节点。这意味着您不能在@Directive
中设置ChangeDetectionStrategy.OnPush
。尽管如此,指令可以具有@Input
和@Output
属性,您可以从中注入和操作主机组件的ChangeDetectorRef
。因此,当您需要对变更检测树进行精细控制时,请使用组件。
【讨论】:
【参考方案6】:在编程上下文中,指令为编译器提供指导以改变其处理输入的方式,即改变某些行为。
“指令允许您将行为附加到 DOM 中的元素。”
指令分为 3 类:
属性 结构 组件是的,在 Angular 2 中,组件是一种指令。 根据文档,
“Angular 组件是指令的子集。与指令不同,组件总是有一个模板,并且模板中的每个元素只能实例化一个组件。”
Angular 2 组件是 Web 组件 概念的实现。 Web 组件由几种不同的技术组成。您可以将 Web 组件视为使用开放式 Web 技术创建的可重用用户界面小部件。
所以在摘要指令中,我们将 行为 附加到 DOM 中的元素的机制,包括结构, 属性和组件类型。 组件是特定类型的指令,它允许我们 利用 Web 组件功能 AKA 可重用性 - 在我们的整个应用程序中提供封装的、可重用的元素。【讨论】:
【参考方案7】:如果您参考官方 angular 文档
https://angular.io/guide/attribute-directives
Angular中有三种指令:
-
组件 - 带有模板的指令。
结构指令—通过添加和删除 DOM 元素来更改 DOM 布局。例如 *ngIf
属性指令—更改元素、组件或其他指令的外观或行为。例如 [ngClass]。
随着应用程序的增长,我们发现很难维护所有这些代码。出于可重用性的目的,我们将我们的逻辑分为智能组件和哑组件,并使用指令(结构或属性)在 DOM 中进行更改。
【讨论】:
【参考方案8】:组件
组件是 Angular 应用程序最基本的 UI 构建块。一个 Angular 应用程序包含一个 Angular 组件树。我们在 Angular 中的应用程序是建立在一个组件树之上的。每个组件都应该有它的模板、样式、生命周期、选择器等。所以,每个组件都有它的结构您可以将它们视为一个独立的小型 Web 应用程序,具有自己的模板和逻辑,并且可以与其他组件通信并一起使用。
组件的示例 .ts 文件:
import Component from '@angular/core';
@Component(
// component attributes
selector: 'app-training',
templateUrl: './app-training.component.html',
styleUrls: ['./app-training.component.less']
)
export class AppTrainingComponent
title = 'my-app-training';
及其 ./app.component.html 模板视图:
Hello title
然后你可以在其他组件中渲染 AppTrainingComponent 模板及其逻辑(添加到模块后)
<div>
<app-training></app-training>
</div>
结果是
<div>
my-app-training
</div>
因为 AppTrainingComponent 在这里渲染
见more about Components
指令
指令更改现有 DOM 元素的外观或行为。例如 [ngStyle] 是一个指令。指令可以扩展组件(可以在其中使用),但它们不会构建整个应用程序。假设它们只支持组件。 它们没有自己的模板(当然,您可以使用它们来操作模板)。
示例指令:
@Directive(
selector: '[appHighlight]'
)
export class HighlightDirective
constructor(private el: ElementRef)
@Input('appHighlight') highlightColor: string;
@HostListener('mouseenter') onMouseEnter()
this.highlight(this.highlightColor || 'red');
private highlight(color: string)
this.el.nativeElement.style.backgroundColor = color;
及其用法:
<p [appHighlight]="color" [otherPar]="someValue">Highlight me!</p>
见more about directives
【讨论】:
【参考方案9】:组件是封装视图和逻辑的单个单元,而指令用于增强组件或 dom 元素的行为,它没有任何模板。
组件扩展指令,因此每个组件都是一个指令。
组件和指令都可以具有生命周期挂钩、输入、输出、提供程序和查询。 组件还可以具有视图提供程序、更改检测策略、 模板、样式和视图封装。我们可以使用组件来构建一个有特色的元素和指令 为元素创建自定义项。
【讨论】:
【参考方案10】:最简单的答案
组件:主要构建块,用于添加一些DOM元素/Html。
指令:用于在DOM元素/HTML中添加一些表达式、条件和循环。
【讨论】:
【参考方案11】:指令:
指令是向元素添加额外行为的类。
不同类型的指令有:
-
组件:这些指令包含模板
属性指令:这些类型的指令改变元素、组件、其他指令的视图或行为
结构指令:这些指令通过添加或删除 DOM 元素来改变 DOM 布局。
【讨论】:
以上是关于Angular 中的 @Directive 与 @Component的主要内容,如果未能解决你的问题,请参考以下文章
Angular 中的 @Directive 与 @Component
Angular 中的 @Directive 与 @Component
Angular 中的 @Directive 与 @Component