A @Component requires a view whereas a @Directive does not.
Directives
I liken a @Directive to an Angular 1.0 directive with the option restrict: 'A'
(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.
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:
CDK is the short form of component dev kit
. This signifies that these are general-purpose tools for building
components that are not coupled to Material Design
From the material2 changelog
- Several components in
core/
, such as Overlay, have had their prefix changed to cdk-
(short
for "component dev kit"). This signifies that these are general-purpose tools for building
components that are not coupled to Material Design.The old selectors are still
available as deprecated but will be removed in the next release. The CSS classes have been changed.
For more info on how to use cdk components such as table, overlay, portal, portal host, e.t.c, you can find examples here:
- https://github.com/angular/material2/tree/master/src/demo-app
- https://medium.com/@caroso1222/a-first-look-into-the-angular-cdk-67e68807ed9b
Best Answer
I know this is old, but I came across this thread while trying to figure out the same exact thing, and after much experimentation, I've figured out a basic working example of a virtually scrolling flat tree that requires VERY LITTLE MODIFICATION if you already have a working cdk-tree
The key to my solution was to abandon the cdk-tree directives and use my MatTreeFlatDataSource and FlatTreeControl directly with *cdkVirtualFor. You probably already have these objects set up to pass as inputs into cdk-tree. cdk-tree is actually just a very light wrapper around these two objects that are doing all of the heavy lifting.
Here's a stackblitz, for a more concrete example: https://stackblitz.com/edit/angular-b5nkkd?file=src/app/app.component.html
Here's what it contains:
Two scrolling flat trees that draw from the same underlying data source and are controlled by the same underlying tree control (i.e, they hold the same data and whatever you do to one tree will be reflected in the other tree as well)
The first tree uses cdk-tree directives, but I couldn't figure out how to get it to work with CDK virtual scroll so it renders all the nodes
The second tree does NOT use cdk-tree, but I was able to get virtual scrolling to work cleanly with very little changes. As a result, you have to do styling and some basic logic yourself, but if you look at the difference in template code in the stackblitz, you'll see that it's not so bad.
I'm displaying the number of nodes each scroll container is rendering to demonstrate that virtual scrolling is working in one and not the other