Master the ngmodule of angular2

Time:2020-11-26

Link to the original text:hacking-with-angular

What we are going to learn today is the modular system of angular2. In general, we use a root module to start our application, and then use many function modules to enrich our application and expand the function of our application. All of these depend on ourNgModuleDecorator, let’s learn about this decorator. Of course, in the process, you will encounter some new instructions, concepts, etc.; but don’t panic, we will explain them in detail one by one in the future articles

Before we start today’s exercise, let’s get familiar with itNgModuleAPI,

interface NgModule {
     //Providers: this option is an array. We need to list some common services of our module
     //Then we can use it in the various components of this module through dependency injection
    providers : Provider[]
     //Declarations: array type options to declare instructions, pipes, etc. belonging to this module
     //Then we can use them in this module
    declarations : Array<Type<any>|any[]>
     //Imports: array type options, our module needs to rely on some other modules, so as to make our module
     //You can directly use some instructions, components and so on provided by other modules
    imports : Array<Type<any>|ModuleWithProviders|any[]>
     //Exports: array type options, some components, instructions and modules that we need to export from this module;
     //If other modules import our module,
     //Then other modules can directly use the components and instruction modules we export here
    exports : Array<Type<any>|any[]>
    //Entrycomponents: an array type option that specifies a series of components that will be compiled when the module is defined
    //Angular creates a componentfactory for each component and stores it in componentfactoryresolver
    entryComponents : Array<Type<any>|any[]>
    //Bootstrap: array type option, which specifies the components that should be started when the module starts. Of course, these components will be automatically added to entrycomponents
    bootstrap : Array<Type<any>|any[]>
    //Schemas: elements or attributes of components or instructions that do not belong to angular need to be declared here
    schemas : Array<SchemaMetadata|any[]>
    //ID: string type option, the hidden ID of the module. It can be a name or a path. It can be used to distinguish modules in getmodulefactory, if the attribute is undefined
    //Then this module will not be registered
    id : string
 }

Well, let’s try a simple example firstquickstartIt’s a useNgModuleSo let’s follow QuickStart on the official website first; if it’s difficult to climb over the wall, you can take a look hereChinese version of QuickStartOr take a look at an example I did on the official websiteangular2-travel.

Let’s take a look at the simplest version of the code firstapp.component.ts:

import { Component } from '@angular/core';
@Component({
    selector: 'my-app',
    templateUrl: 'app/templates/app.template.html'
})
export class AppComponent { }

This is relatively simple to use@ComponentDecorators to define ourAppComponentComponents. The focus isapp.module.tsCode in:

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent }   from './app.component';
@NgModule({
    imports:      [ BrowserModule ],
    declarations: [ AppComponent ],
    bootstrap:    [ AppComponent ]
})
export class AppModule { }

Import firstNgModuleandBrowserModuleas well asAppComponent; ngmodule is necessary for us to organize angular applicationsBrowserModuleIt’s because it provides the basic service providers to start and run browser applications. If you want to learn more about it, check out hereShould I import browsermodule or commonmoduleAfter that, appcomponent is the most basic component that we want to show. Then we can use the@NgModuleThe module we imported is configured in the metadata of, because we need to rely onBrowserModule
So we’re hereimportsAnd then we added it indeclarationsandbootstrapOption addedAppComponentComponents

Of course, we still need to use itmain.tsTo start our entire program:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

What we use here isDynamic boot through just in time JIT compilerOf course, there is another way to run our codeStatic boot using AOT – ahead of – timeStatic scheme can generate smaller and faster applications. It is recommended to use it preferentially, especially in mobile devices or high latency networks. We will not introduce these two methods in detail here. We will introduce the differences between the two methods in future articles
We will use the first method here. The main purpose of this article is to teach you how to use itNgModule.

staymain.tsThe module launched in is generally our root module. Now we want to enrich our root module. First, we will add a small component. Generally, our web application will have a title that changes with the content of the page. Then we will first write such a component: file path:app/components/title/title.component.tsThe code is as follows:

import {Component} from '@angular/core';
@Component({
    selector: 'app-title',
    templateUrl: 'app/components/title/title.template.html'
})

export class TitleComponent {}

We define a component, and its selector isapp-titleThe template of the component is:

<p>Title of the app: dreamapp</p>

Then we add this component to our root template

<h1>My First Angular App</h1>
<app-title></app-title>

Then you will find that our app reported a mistake:

zone.js:355 Unhandled Promise rejection: Template parse errors:
'app-title' is not a known element:
1. If 'app-title' is an Angular component, then verify that it is part of this module.
2. If 'app-title' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '@NgModule.schemas' of this component to suppress this message. ("<h1>My First Angular App</h1>

This is because we did not add this component to our root templatedeclarationsOption, and then we add it in:

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent }   from './app.component';
import {TitleComponent} from "./components/title/title.component";
@NgModule({
    imports:      [ BrowserModule ],
    declarations: [
        AppComponent,
        Titlecomponent // declare the component we just wrote
    ],
    bootstrap:    [ AppComponent ]
})
export class AppModule { }

If you think our component is a bit rigid, we can make it more flexible. We can dynamically pass values to this component and modify it firsttitle.component.ts, importInputAnd then display the input of the component to the component:

import {Component, Input} from '@angular/core';
@Component({
    selector: 'app-title',
    templateUrl: 'app/components/title/title.template.html'
})

export class TitleComponent {
    @Input() appTitle = '';
}

Then modify the template:

<p>Title of application: {{apptitle}}</p>

And then make a changeapp.component.tsThe contents are as follows:

import { Component } from '@angular/core';
@Component({
    selector: 'my-app',
    templateUrl: 'app/templates/app.template.html'
})
export class AppComponent {
    appTitle = 'Hello title';
}

Last revisionapp.template.htmlThe contents are as follows:

<h1>My First Angular App</h1>
<app-title [appTitle]="appTitle"></app-title>

Then our title is now dynamic, it looks good

But our title will not change now. We need to find a way to make it change. The best way is to use the service. Let’s add a service to change the title. Let’s name itActiveTitleServiceRight. The path to the file isapp/components/title/active-title.service.tsThe code is as follows:

import {Injectable} from '@angular/core';

@Injectable()
export class ActiveTitleService {
    getTitle() {
        let title = Math.random().toFixed(2) + 'title';
        return title;
    }
}

Then we need to be inapp.module.tsIn the file, in the@NgModuleAdd to the metadata ofprovidersThen add the service:

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent }   from './app.component';
import {TitleComponent} from "./components/title/title.component";
import {ActiveTitleService} from "./components/title/active-title.service";
@NgModule({
    providers: [
        Activetitleservice // add our previous service
    ],
    imports:      [ BrowserModule ],
    declarations: [
        AppComponent,
        TitleComponent
    ],
    bootstrap:    [ AppComponent ]
})
export class AppModule { }

In the end, it’s in ourapp.component.tsIt uses:

import { Component } from '@angular/core';
import {ActiveTitleService} from "./components/title/active-title.service";
@Component({
    selector: 'my-app',
    templateUrl: 'app/templates/app.template.html'
})
export class AppComponent {
    appTitle = 'Hello title';
    constructor(activeTitleService: ActiveTitleService) {
        //Use this service
        this.appTitle = activeTitleService.getTitle();
    }
}

After adding this service, every time we refresh the page, we will find ourappTitleThen I want to add some styles to my component to make it look better

If we write another instruction like this, we call ithightlightThe file path is:app/components/title/highlight.directive.tsNext, we will be exposed to some new content; but don’t be nervous, these contents will be explained in detail in the following chapters. Now what we need to do is to learn how to use them first, and then achieve the desired effect

import {Directive, ElementRef, Renderer} from '@angular/core';

@Directive({
    selector: '[highlight]'
})

export class HighlightDirective {
    constructor(renderer: Renderer, el: ElementRef) {
        renderer.setElementStyle(el.nativeElement, 'backgroundColor', 'red');
    }
}

We can roughly understand the function of the above instructions, first we importDirectiveThis decorator is used to indicate that the class below us is an instruction class, and then we import itElementRefandRendererIt is used to operate our elements. OK, next we will use this instruction. First of all, we still need to use theapp.module.tsDeclare this instruction in ourtitle.template.htmlUse:

...
declarations: [
        AppComponent,
        TitleComponent,
        HighlightDirective
    ],
...    

Then we use in the template:

< p highlight > title of application: {apptitle}}</p>

The above is all about how to use it in a moduleservice,instructions,assemblyNext, we will write our second module, mainly about how to use it in other modulesservice,instructions,assemblyAnd how to share component instructions among modules

Our second module is a simple list showing some simulated user information; first we create ourUserModuleBecause there are so many files, I will not list them one by one. If you are interested, you can read the specific code of this article on GitHubangular2-travel.

Here isUserModuleI will briefly explain some of the main parts of the structure

.
├── app
    ├── modules 
        ├──  user.module.ts   #User module
    ├── components 
        ╎ -- user list # user list module
            ├──  user.class.ts    #User classes are used to create user instances
            ├── user- highlight.directive.ts  #Instructions
            ├── user- list.component.ts   #Using list components
            ├── user- list.services.ts    #Get user list service
            ├── user- list.template.html  #Template for user list
├── ..

First of alluser.module.tsThis document:

import {NgModule} from '@angular/core';
import {CommonModule} from "@angular/common";
import {FormsModule} from "@angular/forms";
import {UserListComponent} from "../components/user-list/user-list.component";
import {UserListService} from "../components/user-list/user-list.service";
import {HighlightDirective} from "../components/user-list/user-highlight.directive";

@NgModule({
    providers: [
        UserListService
    ],
    imports: [
        CommonModule,
        FormsModule
    ],
    declarations: [
        UserListComponent,
        HighlightDirective
    ],
    exports: [
        CommonModule,
        FormsModule,
        UserListComponent
    ]
})

export class UserModule {}

We redefined a function module and imported the services we neededUserListService, modules we needCommonModuleandFormsModules; then declare the components that can be used in the moduleUserListComponentAnd instructionsHighlightDirectiveFinally, we export some modules and components,
Then we can use it directly in our root moduleUserListComponentDon’t forget to revise itapp.module.tsandapp.template.htmlThey are amended as follows;

First of allapp.module.ts:

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent }   from './app.component';
import {TitleComponent} from "./components/title/title.component";
import {ActiveTitleService} from "./components/title/active-title.service";
import {HighlightDirective} from "./components/title/highlight.directive";
import {UserModule} from "./modules/user.module";
@NgModule({
    providers: [
        ActiveTitleService
    ],
    imports:      [
        BrowserModule,
        Usermodule // add the user module we need
    ],
    declarations: [
        AppComponent,
        TitleComponent,
        HighlightDirective
    ],
    bootstrap:    [ AppComponent ]
})
export class AppModule { }

And then there wasapp.template,html:

<h1>My First Angular App</h1>
<app-title [appTitle]="appTitle"></app-title>
<! -- you can directly use the userlistcomponent -- >
<user-list></user-list>

By now, I think you have a general idea of how to use itNgModuleIf you want to know more about this part, you can take a look hereAngular module (ngmodule)This article is just a brief introduction to it

Finally, if you have any questions, you can go tohereBring it up or leave a message below. Of course, star is welcomeangular2-travelWe hope you can join in and contribute to this project, so that more people can learn to use it betterAngular2