欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

宁皓网 Angular:模块 有大用

   

理解 Angular 的模块。

封面摄影:alfonso maseda varela

来自  https://ninghao.net/course/7769#toc


# git branch         #查看当前分支,,是 http分支

# git checkout master            #切换到master分支

# git merge http 

# git push origin master http            #推送到远程 origin 的master和http分支

# git log --oneline                #当前当前分支的日志,--oneline以一行方式查看,,,,,,,,,,,,,,,,,,,,按 F (forward 向前)键可以向下翻页



# git checkout -b modules 086edaf                        #086edaf是初始化提交的id,基于这次提交可以创建modules分支,并且切换到modules分支


# npm run start                    #其实就是ng serve,启动项目的开发服务


# ng generate module user        #生成一个user模块

CREATE src/app/user/user.module.ts (190 bytes)


先删除user模块文件

# ng generate module user --routing             #生成一个user模块,--routing 同时生成一个路由模块        


# ng generate component user        #生成一个组件

CREATE src/app/user/user.component.html (19 bytes)

CREATE src/app/user/user.component.spec.ts (585 bytes)

CREATE src/app/user/user.component.ts (267 bytes)

CREATE src/app/user/user.component.css (0 bytes)

UPDATE src/app/user/user.module.ts (343 bytes)            #更新对应的模块



ng generate module post --routing --module app            #生成一个user模块,--routing 同时生成一个路由模块,, --module 表示 生成的模块(即post )属于app模块(app模块里会导入生成的post模块)       

CREATE src/app/post/post-routing.module.ts (247 bytes)

CREATE src/app/post/post.module.ts (272 bytes)

UPDATE src/app/app.module.ts (509 bytes)            #更新app模块


D:\angular\ninghao-angular>ng generate component post                #生成组件post

CREATE src/app/post/post.component.html (19 bytes)

CREATE src/app/post/post.component.spec.ts (585 bytes)

CREATE src/app/post/post.component.ts (267 bytes)

CREATE src/app/post/post.component.css (0 bytes)

UPDATE src/app/post/post.module.ts (343 bytes)



介绍与准备

1)准备项目(NgModule)


这个课程我们会介绍一下 Angular 里的模块,可以准备一个全新的 Angular 项目,这样可以把注意力放在理解概念与工具的使用上,如果代码太复杂会有很多干扰。

查看一下项目当前的分支,显示是在 http 这个分支上。把分支切换到 master ,然后在这个分支上做一次合并,合并一下 http 分支。

下面可以推送一下本地的分支,推送到 origin 远程,推送的是 master 还有 http 这两个本地分支。

再查看一下 master 这个分支上的提交日志。加上一个 --oneline,简化一下日志的显示。 按 F 键可以向下翻页,浏览到最后一页。

找到 initial commit 这个提交后面这次提交,配置了编辑器的 Prettier 以后,我做了这次提交,复制一下这次提交的 id 号,基于这次提交可以创建一个新的分支,并且切换到这个分支上,分支的名字是 modules ,后面加上复制的提交的 id 号。

执行 npm run start,运行一下项目的开发服务。

在浏览器上打开项目的开发服务,访问一下 localhost:4200。 现在你看到的就是一个全新的 Angular 项目。

来自  https://ninghao.net/video/7771#info


模块

2)模块(NgModule)


在 Angular 应用里,我们可以根据自己开发的应用的一些功能,去把它们分隔成不同的模块。模块是 Angular 组织应用结构的一种方法。你可以创建一个 Angular 模块,然后把跟这个模块相关的一些东西放在这个模块里,主要就是声明一下这个模块里包含的东西,比如组件、指令,还有 Pipe 等等。

还可以说明一下这个模块需要使用哪些其它的模块里提供的功能,模块也可以选择对外公开提供的东西,这样应用里的其它的模块就可以使用在这个模块里公开提供的这些东西了。

用 Angular 的命令行创建的 Angular 项目里面,已经创建好了一个模块,这个模块是在 src,app,目录的 app.module.ts 这个文件里定义的,定义模块的文件,一般都会有 .module 这个后缀,文件的扩展名是 .ts,表示这个文件里用的语言是 TypeScript,TypeScript 这种语言可以理解成增强版的 JavaScript,它可以让我们使用 JavaScript 里提供的新的功能,还给 JavaScript 语言提供了一个类型系统。

AppModule

Angular 的模块就是一个 class,也就是一个类,这个类的名字就是这个模块的名字。在 Angular 应用里至少需要一个模块,就是这个 AppModule,它是应用的 Root 模块,也就是根模块或者叫主模块。就是你的应用只需要这个 AppModule 模块,可以把应用里所有的东西都放在模块里,不过一般我们都会根据应用的功能,分别再去创建一些功能模块。

@NgModule

让这个普通的类变成一个 Angular 模块,需要用这个 @NgModule 装饰器装饰一下,装饰器其实就是个函数,只不过这种函数有些特别的本领,装饰器可以处理它装饰的东西。

比如在这里,使用 @NgModule 装饰器装饰了这个类,这个类就变成了一个 Angular 的模块,这就是 @NgModule 这个装饰器的作用。 @NgModule 装饰器来自 @angular/core。 Ng 这个前缀就是 Angular 的意思。

参数

@NgModule 装饰器有个对象参数,在这个参数里可以描述一下这个模块。比如这个模块里包含的一些组件,指令,管道这些东西,可以把它们放在 declarations 里面,就是声明一下这个模块包含的东西。这里列出了一个 AppComponent ,它是一个组件。

模块可能需要其它模块提供的东西或者功能,需要把这些要在这个模块里使用的模块,放在 imports 里面。这个 AppModule 模块需要 BrowserModule 还有 AppRoutingModule 这两个模块里提供的东西。providers 里面描述了一下创建的provider

这个 AppModule 模块还有一个 bootstrap,应用在启动的时候,会创建在这个 bootstrap 里列出的组件。通常我们只在这个 AppModule 模块里添加 bootstrap 属性,然后把 AppComponent 这个组件放在这里面。

来自  https://ninghao.net/video/7773#info


3)根组件(AppComponent)


打开应用的首页,页面上显示的内容就是 AppModule 模块里的 AppComponent 这个组件的视图内容。这个组件的视图是在组件的模板里文件里定义的,AppComponent 组件的模块文件是 app.component.html 。

AppComponent 这个组件是在 AppModule 模块的 bootstrap 里面,就是启动的时候要创建的一个组件,因为这个组件是唯一的启动组件,所以这个组件也就是应用里的所有组件的根。

先打开这个组件,定义组件的文件都有个 component 后缀,这个组件设置的它的模板文件就是 app.component.html 文件,组件的 selector 设置成了 app-root。

打开 src 下面的 index.html,这是一个一般的 html 文档的基本结构,我们的 Angular 应用就会在这个文档,你会发现文档里有个 app-root 元素。

因为 AppComponent 组件里设置的 selector 是 app-root,意思就是,把这个组件放在 app-root 元素里面。所以在这个文档用了一组 app-root。

组件的视图是在 app.component.html 这个文件里,剪切一下这个文件里的内容,留下这个 router-outlet,router-outlet 这个地方会显示路由对应的组件内容。

上面添加一组标题,文字是 ninghao。

回到浏览器可以预览一下,现在应用的页面上会显示一个标题,内容是 ninghao。

来自  https://ninghao.net/video/7774#info


4)创建模块


Angular 提供的命令行工具,可以快速创建模块,在终端,项目所在目录的下面,执行 ng generate ,生成一个 module,也就是模块,后面跟着模块的名字,或者保存这个模块的位置跟模块的名字。 比如生成一个 user 模块,执行一下。

ng g m user  ( ng generate module user   )

这样会创建一个 UserModule 模块,放在了 user 目录的下面。

回到项目,打开刚才创建的这个模块,src, app, user 里的这个 user.module.ts。

在这个文件里定义了一个类,名字是 UserModule,这个类用 @NgModule 装饰了一下,所以它就会是一个 Angular 的模块。给这个 @NgModule 提供的对象参数里面,有 declarations 属性,还有一个 imports 属性,它里面列出了一个 CommonModule 模块,这个模块来自 @angular/common。

在这个 CommonModule 模块里提供了一些基本的指令,之所以在这个 UserModule 模块的 imports 里面列出这个模块,是打算在这个 UserModule 模块里使用 CommonModule 里面提供的东西。

来自  https://ninghao.net/video/7775#info


5)创建路由模块


Angular 里面有一种模块是路由模块,就是这种模块的主要作用就是去配置跟功能模块相关的路由。先删除掉之前创建的这个 user 模块。

在创建功能模块的时候可以在命令里面加上一个 --routing 选项,这样就可以自动创建一个对应的路由模块了。ng generate 生成一个 module ,名字是 user,后面加上一个 --routing 选项,

# ng generate module user --routing ( # ng g  m user --routing )

执行一下这个命令。

回到项目,打开 src, app, user,你会发现,刚才执行的命令创建了两个模块,一个是 user 功能模块,还有一个对应的路由模块,一般路由模块跟功能模块在一块儿,模块里带着 routing 后缀,表示这是一个路由模块,注意这只是一个惯用的方法,路由模块的名字没有限制。

打开这个模块看一下,跟一般的模块没什么区别,定义的方法是一样的,只不过,在这个路由模块的 imports 里面,导入了 RouterModule ,用了一下这个 forChild 方法配置了一下路由。RouterModule 来自 @angular/router。在模块的 exports 里面,又导出了这个 RouterModule。

在模块里面的这个 routes 里面,可以配置一下相关的路由。

打开 UserModule,你会发现,在这个模块的 imports 里面,导入了这个 UserRoutingModule。

如果你是手工创建的路由模块,你需要在这个功能模块里,导入它,然后把它放在模块的 imports 里面。

来自  https://ninghao.net/video/7776#info


6)JavaScript 模块与 Angular 模块


在一个 JavaScript 或者 TypeScript 文件里导出了一些东西,这个文件就是一个 JavaScript 模块,在其它文件里可以导入模块,使用它里面导出的东西。因为 TypeScript 代码最终会被编译成 JavaScript 代码,所以这里我们可以认为是 JavaScript 的模块。

打开 Angular 应用的 app.module.ts 这个文件,你会发现,这个文件的顶部,有一些 import 开头的代码,表示导入,导入了一些东西,在 from 后面,设置了一下导入的这个东西的来源是哪里。

如果这个来源不是一个具体的地址,这个来源应该就是我们在项目里安装的 npm 包,也就是在项目的 node_modules 这个目录里面东西。

比如 @angular/core,它就是一个包的名字。因为它即不是一个绝对的地址,也不是一个相对的地址。

下面导入的这个 AppComponent ,它的 from 关键词的后面,是一个相对的地址,一个点加一条斜线表示的是当前目录。相对的是当前这个文件,这里就是 app.module.ts 这个文件。

也就是要导入的 AppComponent 这个东西来自当前目录下面的 app.component.ts 这个文件,在导入的时候可以不加文件的后缀,比如 .js 或者 .ts,直接用文件的名字就可以了。

打开 app.component.ts, 这个文件是一个 JavaScript 模块,模块导出了在这个文件里定义的这个 AppComponent 类。你会发现这个类的定义的前面有个 export,表示要导出后面定义的这个东西,也就是 AppComponent 这个类。

这样在应用里的其它的地方,就可以导入这个模块里导出的这个类了。比如在 app.module.ts 里面,这里就用了一个 import ,导入了 app.component 文件,或者叫模块,导出的 AppComponent 这个类。

也就是 JavaScript 的模块,主要就是为了让我们把代码分别放在一些单独的文件里。

NgModule

Angular 框架本身也用到了模块的概念,不过它跟 JavaScript 语言里的模块不太一样。Angular 模块指的是使用 @NgModule 装饰器装饰的那个类。Angular 模块里也有导入跟导出,模块导入的是这个模块需要的东西,模块导出的是这个模块提供的东西。

来自  https://ninghao.net/video/7777#info


7)理解 Angular 模块的 declarations, exports, imports


Angular 模块拥有的组件,指令,管道这些东西,要把它们放在模块的 declarations 里面。先在终端可以给之前生成的 UserModule 模块创建一个组件。

ng generate 一个 component,名字是 user。 命令会生成一个叫 UserComponent 的组件,

# ng generate component user   ( # ng g c user )

组件会放在 app, user 目录的下面。

打开 user 目录里的这个 UserModule 模块,因为组件的名字是 user,所以命令会自动更新了在 user 目录下面的这个 UserModule 模块。

文件的顶部导入了 user.component 文件里定义的 UserComponent 组件。

declarations

在模块的 declarations 里面,要列出这个模块拥有的东西,这里已经添加好了这个 UserComponent,意思就是这个组件属于 UserModule 这个模块,组件只能属于一个模块。注意这里是命令自动帮我们更新了这个模块文件,如果你是手动创建的组件,你需要自己先在文件顶部导入它,然后把它再添加到这个 declarations 里面。

exports

如果要在其它的模块里使用这个 UserComponent 组件,我们需要先让这个模块导出这个组件,然后在其它的模块里,再导入这个 UserModule 模块。

在 UserModule 里,可以添加一个 exports,在模块导出的东西里面,添加一个 UserComponent,这样其它的模块如果导入 UserModule 模块,就可以使用它的 UserComponent 组件了。

imports

打开 AppModule 模块,我想在这个模块的组件里,用一下 UserModule 模块里的 UserComponent,需要在模块的 imports 里面,导入 UserModule 模块。输入 UserModule,编辑器会自动文件顶部导入 user 目录里的 user.module 文件里导出的 UserModule 。

现在我们就可以在 AppModule 的组件里使用 UserModule 模块里的 UserComponent 组件了。

打开 AppComponent 组件,添加一个 app-user 元素,这是在 UserComponent 组件里设置的 selector,也就是 UserComponent 组件会在这个元素里显示。

预览

回到浏览器可以预览一下。在页面上会显示 UserCompoennt 组件的视图内容。回到项目,去掉 AppModule 模块的导入里添加的这个 UserModule。再回到浏览器试一下。

页面显示空白,在控制台上会出现提示 app-user 是一个未知元素。 这是因为在 AppComponent 所属的 AppModule 模块里,并没有导入 UserModule ,也就不能使用 UserModule 模块里导出的 UserComponent 组件。

恢复一下导入,现在页面就可以正常显示了。

再回到项目,这次打开 UserModule 模块,去掉模块的 exports 里的这个 UserComponent 。 然后回到浏览器预览一下,这次又会提示 app-user 是一个未知元素。

虽然在 AppModule 模块的导入里添加了 UserModule ,但是这次在 UserModule 模块里,并没有在它的导出来说明模块可以对外提供它的 UserComponent 组件,这样在其它的模块里即使导入了 UserModule 模块,也不能使用模块里的 UserComponent 组件。

回到 UserModule 模块,恢复一下导出这个 UserComponent,再到浏览器上预览一下,这回就可以正常显示 UserComponent 组件的视图内容了。

来自  https://ninghao.net/video/7778#info


8)功能模块


在终端给应用再创建一个功能模块,ng generate 一个 module 名字是 post ,加上 --routing 选项顺便创建一个对应的路由模块,然后可以再用 --module 选项设置一下包含这个模块的模块,这里设置成 app,

# ng g m post --routing --module app ( # ng generate module post --routing --module app  )

这样会在应用的 AppModule 模块里导入这里创建的这个模块。

接着再给这个模块添加一个组件,ng generate 一个 component 名字是 post 。

# ng generate component post ( # ng g c post )

回到项目,打开刚才创建的 PostModule 模块,在这个模块的 Declarations 里面,已经声明了 PostComponent 组件。注意在这个模块里,并没有导出 PostComponent。

下面打开应用的根路由模块,就是这个 AppRoutingModule 模块。在它的 routes 里面可以定义一条路由,一个对象,用 path 设置一下路由地址,用一个空白,表示应用的根。然后用 component 设置一下对应的组件,可以用一下 PostComponent 。

再打开 UserRoutingModule 这个路由功能模块,在它的 routes 里面,添加一条路由,路由的 path 是 users,路由的 component 设置成 UserComponent。

在 Angular 的路由定义里设置的组件,都会是 entryComponent。

打开 UserModule 模块,可以去掉里面的 exports 。

然后打开 AppComponent 组件的模板文件,去掉这里用的 app-user。 一组 a 标签,链接文字是 Home,在这个 a 元素上添加一个 routerLink,地址是 / 表示应用的根。

再添加一组 a 标签,文字是 Users,使用一个 routerLink ,地址是 /users 。

预览

回到浏览器,可以预览一下,现在是在应用的首页,页面上会显示 PostComponent 组件的视图内容, 再按一下 Users 这个链接 ,打开的地址是 users,页面上显示的是 UserComponent 组件的视图内容。

来自   https://ninghao.net/video/7779#info


9)按需加载模块(Lazy Loading)


访问应用首页的时候,并不需要 UserModule 模块提供的功能,我们可以延迟加载这个模块,就是按需加载模块。英文是 Lazy loading。 用户只有在访问 Users 这个链接的时候才会加载需要的 UserModule 模块。

回到项目,打开 User 模块的路由模块,UserRoutingModule,去掉这条路由里的 users,只留下一个空白。

然后打开应用的根路由模块,AppRoutingModule ,在这里可以添加一条新的路由,路由的 path 设置成 users,然后用一个 loadChildren 属性,它的值是个方法,方法做的事可以用一下 import ,导入要加载的模块,模块的位置是当前目录下的 user 里面的 user.module,导入会返回 promise,所以接着用一个 then ,结果是 module ,返回 module 里的 UserModule 。

打开 AppModule 模块,这里要去掉导入进来的 UserModule 模块,因为现在这个模块需要按需加载它。(懒惰式 加载 模块 Lazy loading 模块)

预览

回到浏览器可以试一下,打开浏览器开发者工具里的 Network 这个选项卡, 过滤出 JS,现在应用还没有加载 UserModule 模块的代码。

访问一下 Users 链接,这时候应用才会加载 UserModule 模块的代码。


来自  https://ninghao.net/video/7780

普通分类: