This course has been updated! We now recommend you take the Angular 9 Fundamentals course.
Transcript from the "Angular Building Blocks 1" Lesson
>> Lukas: The big picture. This is pretty close to what is on the website. I have just made it a bit more colorful, but these are the big pieces that I want to call out. So again, we have the template and controller pair. When I say controller, it's now a component, which is just really a class.
[00:00:28] And then you have the metadata that binds those two together. So in Angular 1 you had your template and controller, and you had scope kind of binding that together and telling you basically the controller and the template, how they were going to behave. Now you have template and component with your metadata pulling those two together.
[00:00:47] Then on one side you have the directive. So a component is actually a directive with a template attached to it. You have a directive that just is straight functionality, but again is just a class that provides functionality to an element. And so think of it as essentially a component without a template, or you can think of a component as a directive with a template.
[00:01:14] But very similar, and you'll actually start to see a lot of these common themes as we go through these. And then for a service is, it's just a class. The beauty of this is, your component, your directive, and your service are just classes that you then go in and annotate to perform specific functions.
[00:01:32] And so I find that when you kind of stop and look at this, you realize, there's not really too many pieces on the board. It's just services, components, templates, directives, and then you have the binding that it's pretty simple. And then you have essentially a module that's wrapping everything that makes that really kind of easy to not to be as scared as when I first saw, of like, we're killing everything!
[00:01:59] And it's like, what's it going to look like? And it was really fuzzy at first. But then once I kind of stopped and thought about it in these terms, it became a lot simpler and less intimidating. Also, I forgot to mention, this is the too long dint watch module, so I'm going to talk quite a bit here.
[00:02:21] I apologize for that. But if anybody was going to at the end of this module, close their laptop lid and be like, I'm going to the beach, then you could probably still, if you remember some of these, make the case to your boss that this was a good investment in your career.
[00:02:37] So the main building blocks, module, component, metadata, template, data binding, service, directive, and dependency injection. So let's be about it. So first and foremost, let's talk about how to bootstrap the app. This is the genesis of an Angular 2 application. In Angular 1 it was ng-app and then you would put your module in.
[00:02:58] In Angular 2 it's a little different. You import the bootstrap module. You import your dependencies for your application. Then you import your top level component. So for every Angular application, you have a top level component that lives within your main page, and that's like the entry point for your application.
[00:03:25] And so in this case we're going to call it, appropriately, app component. And so it's kind of similar in nature to Angular 1, but we're importing the bootstrap module, our router providers, and AppComponent, which is our top level component. And we're just saying bootstrap. We're calling this method.
[00:03:44] We're passing in the AppComponent, so we're saying bootstrap the application with this AppComponent. And here are the ROUTER_PROVIDERS as a top level application dependency.
>> Lukas: And so now this leads to the next question, well, what is a module? Well, Angular 2 uses modules as the core mechanism for composition.
[00:04:10] Just like in Angular 1, I think philosophically it's just a mechanism for dividing up your application and providing containers. And we use the ES6 module syntax. So not only do we have kind of this philosophical construct of we're organizing our application into modules, but it comes with actual ES6.
[00:04:36] We're using the ES6 mechanisms to do that. So modules, they export things so that we can import them in other places. So in this case, export class HomeComponent, import HomeComponent from home.component. So we'll start to look at the syntax. This is just a tour of what we're going to cover for the next two days.
[00:05:00] So we have a module. Now we have a component. So modules should be fairly fine grained and kind of single responsibility. Within a module then you have a component which is just an ES6 class. And when you need a provider, you just inject that into the constructor of your component class.
[00:05:23] And we need to explicitly within our metadata define what directives and what providers we're using when we decorate it. You can also, and this is really neat, hook into the actual application lifecycle with component hooks. And so in this case we have the HomeComponent and we're implementing the OnInit interface.
[00:05:51] So this is some TypeScript kind of sugar. We'll talk about TypeScript in a little bit, but this helps, I think, convey intent, that HomeComponent implements OnInit, and then you have the ngOnInit method, so when you're application has initialized, then essentially this method gets called. It's a lifecycle hook that hey, this thing is initialized, let's go ahead and get this thing.
[00:06:17] And then you can see here I'm injecting the stateService in my constructor, so now it's available for the rest of my application. As well as when you use an Angular 1.x controllerAs, your methods and properties that exist on your controller are now available to your template. Same thing here, title, body, message, now that's available to bind to in my template, and updateMessage as well.
[00:07:14] But then we can come in very unobtrusively and add in our metadata to say we want this class. We want to bind it or point it to this component. And they're just functions under the hood. You can do this manually using ES6, ES5. But I think the easiest thing to do is just use TypeScript metadata that gets compiled into something.
[00:08:10] So pretty simple, you have a class and you're using metadata to basically bind it to a template that Angular can then render when it sees it in the view.
>> Lukas: Speaking of templates, this again is just compiled HTML. And two very interesting things about Angular 2 templates is that it's leveraging DOM native events, I mentioned that, and properties, and so you have a lot less Angular footprint in your code.
[00:08:44] And it also leverages shadow DOM to do some really interesting things in terms of view encapsulation. And so for instance, by default, that if you define some styles on a component, Angular will compile that to only be applied to that component. So you're actually allowed to encapsulate particular styling and various markup things for that.
[00:09:06] And what that does is it'll go through and kind of generate kind of this quasi-shadow DOM under the hood for you.
>> Lukas: And so again, you have the template, the metadata, the component, and then we have property bindings that bind properties from the component to the template. And then the template can bind to events and pass those into the component.
[00:09:30] And so here is another example of some metadata. You could put styles in here inline. So these styles that we've defined here is now specific to the experiment component, so it's been encapsulated. Or you can say I would prefer not to have that and actually have this be applied across the board.
[00:09:51] You can set ViewEncapsulation to none.
>> Lukas: So we're gonna take a small detour quickly and we're gonna talk about best practices. In Angular 1 when I did a directive, I would actually separate out my template into a separate file. And my reasoning was that it was easier for designers, UI types, to go and do my markup while I build out my component.
[00:10:25] With Angular 2, that sentiment has changed, so you can still use template URL. But it's considered best practice to keep your components very small and very specific insomuch that the markup for that component can fit comfortably with inline within your component metadata. And so the idea is that if all the sudden now your inline template is becoming painful to work on, or it's like, this is 80 lines of HTML in this inline template, you might wanna stop and be like, maybe it makes sense to actually break this out and kind of use this as a metric for am I doing so much in this component?
[00:11:11] So that is kind of the generally accepted best practices. I think that is influenced from React and how they think about components is that keep your components so small that the templates for them comfortably fit within the component. One caveat to that I've personally found, this is not gospel, is that forms generally come with just a lot of markup, and so if you are doing a non-trivial form, then I probably would pull that out into a separate file.
[00:11:41] But by doing it inline, everything gets completely compiled and it will save you an actual async request as well. So there's some performance considerations there.