Angular中的@Directive与@Component


441

@Component@DirectiveAngular有什么区别?他们两个似乎完成相同的任务,并具有相同的属性。

用例是什么?何时优先使用一个?


13
一个组件是与模板的指令@Component装饰实际上是一个@Directive装饰扩展面向模板的功能-
Cosmin Ababei 2016年

2
指令与组件是新的服务与工厂。混淆也增加了,因为当实际需要组件定义中的其他组件时,您需要在directives数组中指定它们...也许下面的Lida Weng评论可以帮助您澄清组件“实际上是扩展的'指令'”
Nobita

1
组件实际上是扩展指令,它们只需要您有一个模板(HTML)即可,而不是指令。.因此,您将使用指令来修改现有的html元素,而组件会制作html元素
Marko Niciforovic

Answers:


544

@Component需要视图,而@Directive则不需要。

指令

我将@Directive类似于带有选项的Angular 1.0指令restrict: 'A'(指令不限于属性用法。)指令将行为添加到现有DOM元素或现有组件实例中。指令的一个示例用例是记录对元素的单击。

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元素时,请编写指令。

资料来源:


2
@directive注释是否具有template / templateUrl属性?
Pardeep

7
这个答案仍然正确吗?angular2教程本身会创建一个没有视图的组件
Tamas Hegedus

它没有视图,但是在组件中必须使用templateurl或template
Luca Trazzi

4
我喜欢这种答案,但是当框架发生重大更改时,我将不胜感激。
米特·奥尔森

这需要稍作更改。角度2 API已更改。不再有View装饰器。
DaSch

79

组件

  1. 要注册组件,我们使用@Component元数据注释。
  2. Component是一个指令,它使用影子DOM创建封装的可视行为(称为组件)。组件通常用于创建UI小部件。
  3. 组件用于将应用程序分解为较小的组件。
  4. 每个DOM元素只能存在一个组件。
  5. @View 装饰器或templateurl模板在组件中是必需的。

指示

  1. 要注册指令,我们使用@Directive元数据注释。
  2. 指令用于向现有DOM元素添加行为。
  3. 指令用于设计可重复使用的组件。
  4. 每个DOM元素可以使用许多指令。
  5. 指令不使用View。

资料来源:

http://www.codeandyou.com/2016/01/difference-between-component-and-directive-in-Angular2.html


5
组件-第4点。我认为这是错误的-可以多次使用。实际上是扩展的“指令”
Lida Weng

本可以用示例来扩展它。
Mukus's

它并不总是Shadow Dom。取决于视图封装
Anirudha

63

组件是带有模板的指令,@Component装饰器实际上是@Directive具有面向模板功能的装饰器。


3
不知道为什么您投票过多。看来@Component对我来说是带有模板(生成视图)的指令。
哈里·宁

22

在Angular 2及更高版本中,“一切都是组成部分。” 组件是通过在现有组件中添加功能的自定义元素和属性来构建和指定页面上的元素和逻辑的主要方式。

http://learnangular2.com/components/

但是,在Angular2 +中会执行哪些指令?

属性指令将行为附加到元素。

Angular中有三种指令:

  1. 组件-带有模板的指令。
  2. 结构化指令-通过添加和删除DOM元素来更改DOM布局。
  3. 属性指令-更改元素,组件或其他指令的外观或行为。

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中使用标记时,将创建此组件,并调用并呈现构造函数。


7

变更检测

只能@Component是变更检测树中的节点。这意味着你不能设置ChangeDetectionStrategy.OnPush一个@Directive。尽管如此,指令仍可以具有@Input@Output属性,并且您可以从中注入和操纵主机组件ChangeDetectorRef。因此,当您需要对变更检测树进行精细控制时,请使用“组件”。


6

在编程环境中,指令为编译器提供了指导,以改变编译器将如何处理输入,即更改某些行为。

“指令允许您将行为附加到DOM中的元素。”

指令分为3类:

  • 属性
  • 结构性
  • 零件

是的,在Angular 2中,组件是一种指令。根据文件,

角组件是指令的子集。与指令不同,组件始终具有一个模板,并且模板中每个元素只能实例化一个组件。”

Angular 2组件是Web组件概念的实现。Web组件包含几种单独的技术。您可以将Web组件视为使用开放Web技术创建的可重用的用户界面小部件。

  • 因此,在摘要指令中,我们将行为附加到DOM中的元素的机制,该机制由“结构”,“属性”和“组件”类型组成。
  • 组件是一种特殊的指令类型,它使我们能够利用Web组件的功能,即 AKA可重用性-在整个应用程序中可用的封装的可重用元素。

2

如果您参考官方的角度文档

https://angular.io/guide/attribute-directives

Angular中有三种指令:

  1. 组件-带有模板的指令。
  2. 结构化指令-通过添加和删除DOM元素来更改DOM布局。例如* ngIf
  3. 属性指令-更改元素,组件或其他指令的外观或行为。例如[ngClass]。

随着应用程序的增长,我们发现很难维护所有这些代码。出于可重用性的目的,我们将逻辑分为智能组件和哑组件,并使用指令(结构或属性)在DOM中进行更改。


1

组件

组件是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在此处呈现

参见更多组件

指令

指令更改现有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>

参见更多指令

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.