@Directive vs @Component in Angular
Solution 1:
A @Component requires a view whereas a @Directive does not.
Directives
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>
Components
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.
In summary
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:
- @Directive documentation
- @Component documentation
- Helpful blog post
Solution 2:
Components
- To register a component we use
@Component
meta-data annotation. - Component is a directive which uses shadow DOM to create encapsulated visual behavior called components. Components are typically used to create UI widgets.
- Component is used to break up the application into smaller components.
- Only one component can be present per DOM element.
-
@View
decorator or templateurl template are mandatory in the component.
Directive
- To register directives we use
@Directive
meta-data annotation. - Directive is used to add behavior to an existing DOM element.
- Directive is use to design re-usable components.
- Many directives can be used per DOM element.
- Directive doesn't use View.
Sources:
https://www.devdiscuss.com/difference-between-component-and-directive-in-angular-2/
Solution 3:
A component is a directive-with-a-template and the @Component
decorator is actually a @Directive
decorator extended with template-oriented features.
Solution 4:
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.