What is the difference between @Component and @Directive in Angular?
Both of them seem to do the same task and have the same attributes.
What are the use cases and when to prefer one over another?
A @Component requires a view whereas a @Directive does not.
I liken a @Directive to an Angular 1.0 directive with the option (Directives aren't limited to attribute usage.) Directives add behaviour to an existing DOM element or an existing component instance. One example use case for a directive would be to log a click on an element.restrict: 'A'
import {Directive} from '@angular/core';
@Directive({
selector: "[logOnClick]",
hostListeners: {
'click': 'onClick()',
},
})
class LogOnClick {
constructor() {}
onClick() { console.log('Element clicked!'); }
}
Which would be used like so:
<button logOnClick>I log when clicked!</button>
A component, rather than adding/modifying behaviour, actually creates its own view (hierarchy of DOM elements) with attached behaviour. An example use case for this might be a contact card component:
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() {}
}
Which would be used like so:
<contact-card [name]="'foo'" [city]="'bar'"></contact-card>
ContactCard is a reusable UI component that we could use anywhere in our application, even within other components. These basically make up the UI building blocks of our applications.
Write a component when you want to create a reusable set of DOM elements of UI with custom behaviour. Write a directive when you want to write reusable behaviour to supplement existing DOM elements.
Sources:
Components
@Component meta-data annotation.@View decorator or templateurl template are mandatory in the component.Directive
@Directive meta-data annotation.Sources:
http://www.codeandyou.com/2016/01/difference-between-component-and-directive-in-Angular2.html
A component is a directive-with-a-template and the @Component decorator is actually a @Directive decorator extended with template-oriented features.
In Angular 2 and above, “everything is a component.” Components are the main way we build and specify elements and logic on the page, through both custom elements and attributes that add functionality to our existing components.
http://learnangular2.com/components/
But what directives do then in Angular2+ ?
Attribute directives attach behaviour to elements.
There are three kinds of directives in Angular:
- Components—directives with a template.
- Structural directives—change the DOM layout by adding and removing DOM elements.
- Attribute directives—change the appearance or behaviour of an element, component, or another directive.
https://angular.io/docs/ts/latest/guide/attribute-directives.html
So what's happening in Angular2 and above is Directives are attributes which add functionalities to elements and components.
Look at the sample below from Angular.io:
import { Directive, ElementRef, Input } from '@angular/core';
@Directive({ selector: '[myHighlight]' })
export class HighlightDirective {
constructor(el: ElementRef) {
el.nativeElement.style.backgroundColor = 'yellow';
}
}
So what it does, it will extends you components and HTML elements with adding yellow background and you can use it as below:
<p myHighlight>Highlight me!</p>
But components will create full elements with all functionalities like below:
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)
}
}
and you can use it as below:
<my-component></my-component>
When we use the tag in the HTML, this component will be created and the constructor get called and rendered.
Only @Component can be a node in the change detection tree. This means that you cannot set ChangeDetectionStrategy.OnPush in a @Directive. Despite this fact, a Directive can have @Input and @Output properties and you can inject and manipulate host component's ChangeDetectorRef from it. So use Components when you need a granular control over your change detection tree.
In a programming context, directives provide guidance to the compiler to alter how it would otherwise process input, i.e change some behaviour.
“Directives allow you to attach behavior to elements in the DOM.”
directives are split into the 3 categories:
Yes, in Angular 2, Components are a type of Directive. According to the Doc,
“Angular components are a subset of directives. Unlike directives, components always have a template and only one component can be instantiated per an element in a template.”
Angular 2 Components are an implementation of the Web Component concept. Web Components consists of several separate technologies. You can think of Web Components as reusable user interface widgets that are created using open Web technology.
If you refer the official angular docs
https://angular.io/guide/attribute-directives
There are three kinds of directives in Angular:
As the Application grows we find difficulty in maintaining all these codes. For reusability purpose, we separate our logic in smart components and dumb components and we use directives (structural or attribute) to make changes in the DOM.
@Componentdecorator is actually a@Directivedecorator extended with template-oriented features - source. - Cosmin Ababeidirectivesarray... maybe Lida Weng comment below helps a bit clarifying that the component "it's actually an extended 'Directive' " - Nobita