学习 Angular 教程 - 第五部分





5.00/5 (6投票s)
实现懒加载路由以及在 Angular 中使用 Jquery
目录
其余文章的链接
- 在第一部分,我们研究了 Node、TypeScript、模块加载器/打包器和 VS Code。
- 在第二篇文章中,我们创建了一个带有屏幕的简单基础 Angular 应用程序,并介绍了组件和模块等重要概念。
- 在第三篇文章中,我们研究了如何实现 SPA 和验证。
- 在第四篇文章中,我们了解了如何进行 HTTP 调用以及如何使用 Input 和 Output 创建自定义 Angular 组件。
- 在第五部分中,我们涵盖了两个实验 - 一个是如何在 Angular 中使用 Jquery 和延迟路由。
- 在第六部分中,我们再次涵盖了两个实验 - 使用提供者的管道和 DI。
在本文中,我们将看到如何实现延迟路由以及如何在 Angular 中使用 JQuery。
实验 11:使用动态路由进行延迟加载
理论
大型项目会有很多组件和模块,换句话说,我们最终会在浏览器客户端有很多 JS 文件。在客户端浏览器一次性加载这些 JS 文件会严重影响性能。
如果您在此阶段加载当前应用程序并查看开发人员工具,您将在网络选项卡中看到所有 JS 文件都在启动时加载。 当用户第一次访问网站时,我们希望只加载欢迎组件和主组件的 JS。 当用户单击供应商和客户时,相应的 JS 文件应该在那时加载。 | |
让我们调查一下罪魁祸首是谁? 如果您查看我们项目的当前架构,我们有一个模块 (MainModule.ts),所有组件目前都属于这一个模块。因此,当这个模块加载时,它会加载它内部的所有组件。 简单来说,我们需要将模块分解成单独的物理模块文件。 | |
步骤 1:创建三个不同的物理模块
正如理论的前一部分所讨论的,我们首先需要将项目划分为三个不同的物理模块文件:MainModule
、SupplierModule
和 CustomerModule
。
因此,在 module 文件夹中,让我们创建三个不同的物理模块文件。我们已经有了 MainModule.ts,我们需要再创建两个。 MainModule.ts:此模块将加载“MasterPageComponent.ts”和“WelcomeComponent.ts”。 SupplierModule.ts:此模块将加载“SupplierComponent.ts”。 CustomerModule.ts:这将加载 | |
步骤 2:从 MainModule 中移除 Supplier 和 CustomerComponent
首先,我们需要从 MainModule
中移除 CustomerComponent
、SupplierComponent
和 GridComponent
的所有引用。下面是需要从 MainModule
中移除的划掉的源代码。在主模块中,我们只引用了 WelcomeComponent
和 MastePageComponent
。
★当模块之间不存在导入时,这两个模块是解耦的。即使您不使用该组件并且存在导入,解耦也不完整,JS 仍将被加载。
Lot of Code has been removed for clarity. Please download source code
for full code.
import { CustomerComponent } from '../Component/CustomerComponent';
import { SupplierComponent } from '../Component/SupplierComponent';
import { WelcomeComponent } from '../Component/WelcomeComponent';
import { GridComponent } from '../Component/GridComponent';
import { MasterPageComponent } from '../Component/MasterPageComponent';
@NgModule({
imports: [RouterModule.forRoot(ApplicationRoutes),
InMemoryWebApiModule.forRoot(CustomerApiService),
BrowserModule,ReactiveFormsModule,
FormsModule,HttpModule],
declarations: [CustomerComponent,
MasterPageComponent,
SupplierComponent,
WelcomeComponent,
GridComponent],
bootstrap: [MasterPageComponent]
})
export class MainModuleLibrary { }
步骤 3:创建不同的路由文件
如前所述,“一个简单的导入引用”会使两个模块耦合。如果模块是耦合的,这些 JS 文件将被加载。 如果您还记得,“MainModule.ts”从“Routing.ts”加载路由,而 Routing.ts 具有对 因此加载路由也会加载其他组件,我们将无法实现延迟加载。 因此,让我们从 MainModule.ts 中移除 | |
import {Component} from '@angular/core';
import {CustomerComponent} from '../Component/CustomerComponent';
import {SupplierComponent} from "../Component/SupplierComponent";
import {WelcomeComponent} from "../Component/WelcomeComponent";
export const ApplicationRoutes = [
{ path: 'Customer', component: CustomerComponent },
{ path: 'Supplier', component: SupplierComponent },
{ path: '', component:WelcomeComponent },
{ path: 'UI/Index.html', component:WelcomeComponent }
];
但是,我们仍然需要为“Customer
”和“Supplier
”定义路由,同时不能使用“import
”语句,因为它会使模块耦合。如果您查看当前定义路由的语法,我们需要在 import
中包含该组件,否则我们无法定义路由。
{ path: 'CustomerComponent', component:CustomerComponent },
为此,Angular 提供了一个很好的属性,称为“loadChildren
”。在“loadChildren
”中,我们需要像 string
一样用单引号给出模块。这意味着这将在运行时而不是编译时进行评估。
{
path: 'Customer',
loadChildren:'../Module/CustomerModuleLibrary#CustomerModuleLibrary'
}
“loadChildren
”的结构应遵循此模式
路由的完整代码将如下图所示
import {Component} from '@angular/core';
import {WelcomeComponent} from "../Component/WelcomeComponent";
export const ApplicationRoutes = [
{ path: 'Customer',
loadChildren:'../Module/CustomerModuleLibrary#CustomerModuleLibrary' },
{ path: 'Supplier',
loadChildren: '../Module/SupplierModuleLibrary#SupplierModuleLibrary' },
{ path: '', component:WelcomeComponent },
{ path: 'UI/Index.html', component:WelcomeComponent },
{ path: 'UI', component:WelcomeComponent }
];
我们还需要再创建两个路由文件,一个用于“Customer
”,一个用于“Supplier
”,如下图所示
import {Component} from '@angular/core';
import {CustomerComponent} from "../Component/CustomerComponent";
export const CustomerRoutes = [
{ path: 'Add', component:CustomerComponent }
];
import {Component} from '@angular/core';
import {SupplierComponent} from "../Component/SupplierComponent";
export const SupplierRoutes = [
{ path: 'Add', component:SupplierComponent }
];
“SupplierRoutes
”和“CustomerRoutes
”是子路由,而“ApplicationRoutes
”是父路由。
步骤 4:在 Supplier 和 Customer 模块中调用子路由
在 supplier
模块和 customer
模块中,我们需要加载它们在“步骤 3”中定义的相应路由。要加载子路由,我们需要使用“RouterModule.forChild
”。
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import {FormsModule , ReactiveFormsModule} from "@angular/forms"
import { SupplierComponent } from '../Component/SupplierComponent';
import { RouterModule } from '@angular/router';
import { SupplierRoutes } from '../Routing/SupplierRouting';
import {CustomerApiService} from "../Api/CustomerApi"
@NgModule({
imports: [RouterModule.forChild(SupplierRoutes),
CommonModule,ReactiveFormsModule,
FormsModule],
declarations: [SupplierComponent],
bootstrap: [SupplierComponent]
})
export class SupplierModuleLibrary { }
同样,我们需要为 Customer
模块执行此操作。
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import {FormsModule , ReactiveFormsModule} from "@angular/forms"
import { CustomerComponent } from '../Component/CustomerComponent';
import { GridComponent } from '../Component/GridComponent';
import { RouterModule } from '@angular/router';
import { CustomerRoutes } from '../Routing/CustomerRouting';
import { InMemoryWebApiModule } from 'angular2-in-memory-web-api';
import {CustomerApiService} from "../Api/CustomerApi"
import { HttpModule } from '@angular/http';
@NgModule({
imports: [RouterModule.forChild(CustomerRoutes),
InMemoryWebApiModule.forRoot(CustomerApiService),
CommonModule,ReactiveFormsModule,
FormsModule,HttpModule],
declarations: [CustomerComponent,
GridComponent],
bootstrap: [CustomerComponent]
})
export class CustomerModuleLibrary { }
步骤 5:配置路由链接
在步骤 3 和 4 中,我们定义了父路由和子路由。父路由在“Routing.ts”中定义,而子路由在“CustomerRouting.ts”和“SupplierRouting.ts”中定义。因此,现在路由链接必须更改为“ | |
<a [routerLink]="['Supplier/Add']">Supplier</a> <br />
<a [routerLink]="['Customer/Add']">Customer</a><br>
现在,主页的完整代码如下所示
<table border="0" width="100%">
<tr>
<td width="20%"><img src="http://www.questpond.com/img/logo.jpg" alt="Alternate Text" />
</td>
<td width="80%">Questpond.com Private limited</td>
</tr>
<tr>
<td valign=top>Left Menu<br />
<a [routerLink]="['Supplier/Add']">Supplier</a> <br />
<a [routerLink]="['Customer/Add']">Customer</a><br>
<a [routerLink]="['']">Home</a>
</td>
<td>
<div id=”dynamicscreen”>
<router-outlet></router-outlet>
</div>
</td>
</tr>
<tr>
<td></td>
<td>Copy right @Questpond</td>
</tr>
</table>
步骤 6:将浏览器模块替换为通用模块
“BrowserModule
”和“CommonModule
”是 Angular 的模块。“BrowserModule
”包含启动服务和启动应用程序的代码,而“CommonModule
”包含“NgIf
”和“NgFor
”等指令。
“BrowserModule
”重新导出了“CommonModule
”。或者简单来说,“BrowserModule
”使用了“CommonModule
”。所以如果你加载“BrowserModule
”,你也会加载“CommonModule
”。
所以现在如果你在所有三个模块中都加载“ 因此,如果所有三个模块中都有“ 此错误表示“ | |
因此,在主模块中,加载浏览器模块,在其余模块中,加载“CommonModule
”。
import { BrowserModule } from '@angular/platform-browser';
// Other imports have been removed for clarity
@NgModule({
imports: [RouterModule.forRoot(ApplicationRoutes),
InMemoryWebApiModule.forRoot(CustomerApiService),
BrowserModule,ReactiveFormsModule,
FormsModule,HttpModule],
declarations: [
MasterPageComponent,
WelcomeComponent],
bootstrap: [MasterPageComponent]
})
export class MainModuleLibrary { }
但在客户和供应商模块中,只加载通用模块。
import { CommonModule } from '@angular/common';
// other imports has been removed for clarity
@NgModule({
imports: [RouterModule.forChild(SupplierRoutes),
CommonModule,ReactiveFormsModule,
FormsModule],
declarations: [SupplierComponent],
bootstrap: [SupplierComponent]
})
export class SupplierModuleLibrary { }
import { CommonModule } from '@angular/common';
// Other import has been removed for claroty
@NgModule({
imports: [RouterModule.forChild(CustomerRoutes),
InMemoryWebApiModule.forRoot(CustomerApiService),
CommonModule,ReactiveFormsModule,
FormsModule,HttpModule],
declarations: [CustomerComponent,
GridComponent],
bootstrap: [CustomerComponent]
})
export class CustomerModuleLibrary { }
步骤 7:检查延迟加载是否正常工作
现在运行您的应用程序,转到网络选项卡并检查延迟加载是否正常工作。您可以看到当应用程序启动时,只加载了“WelcomeComponent
”和“MasterPageComponent
”。一旦您单击 supplier
和 customer
,相应的组件将在此刻加载。
请设置适当的过滤器,以便您在网络中不会看到所有 JS 文件。
实验 12:在 Angular 中使用 jQuery
引言
jQuery 是一个非常古老且值得信赖的 JavaScript 框架。它拥有许多稳定且值得信赖的 UI 组件。作为惯例,您不应将 jQuery 与 Angular 一起使用,因为它们都可能与 DOM 操作重叠,导致混淆。
jQuery 使用“ 因此,jQuery 可以操作 HTML DOM,而 Angular 不了解这种操作,从而造成更多混淆。 | ![]() |
但是,有时我们希望使用 jQuery UI 组件,例如 Angular 中可能没有的 jQuery 网格、jQuery 日历等。
★如果 Angular 是您的主要框架,那么首先查看您是否可以在 Angular 中获得解决方案,如果不能,则使用 jQuery 或任何其他框架。
在这个实验中,我们将使用 jQuery 来使我们的网格组件淡入淡出。因此,让我们创建一个名为 Hide Grid 的按钮。当最终用户单击 Hide Grid 时,网格应逐渐变得可见和不可见。
步骤 1:安装 JQuery
因此,第一步是获取 jQuery。让我们启动节点命令,同时获取 jQuery,并将其条目保存到“package.json”文件中。
npm install jquery –save
步骤 2:安装 JQuery 类型定义
JavaScript 分为两代,一代是 TypeScript 之前,即纯 JavaScript,另一代是 TypeScript 之后。JavaScript 是一种动态的无类型语言,而 TypeScript 是强类型语言。我们可以调用不存在的方法,分配未创建的变量等等。
另一方面,TypeScript 是强类型语言。所有事情都在设计时/编译时完成,TypeScript 必须预先了解方法、参数等所有内容。
现在,像 jQuery 这样的框架是用纯 JavaScript 编写的,因此如果要在 TypeScript 中使用它们,我们需要暴露它们的类型、参数等。这就是我们需要创建类型定义文件的地方。类型定义是 TypeScript 文件,它们暴露 JavaScript 对象的形状和结构,以便 TypeScript 可以在设计时理解 JavaScript 类型。
您一定想知道我们是否需要手动创建类型定义文件?不,您不需要。jQuery 已经有类型定义,相反,几乎所有流行的 JavaScript 框架都有它们的类型定义文件。
因此,要获取 jQuery 类型定义,我们需要通过指向“@types/jquery
”进行 npm install。实际上,您可以使用“@types
”加载任何类型,例如,如果您想加载 lodash,您可以对“@types/lodash
”执行“npm install
”。
npm install @types/jquery –save
步骤 3:在 UI 中提供 ID
jQuery 使用选择器引用 HTML UI 元素。在选择器中,我们需要提供名称或 ID,通过它们我们可以获取该 HTML 元素的引用。因此,让我们将我们的“grid
”组件包装在一个 DIV
标签中,并为其分配一些“id
”值,就像我们在下面的代码中给出的“divgrid
”一样。
此外,我们创建了一个调用组件中“Fade
”方法的按钮。
<input (click)="Fade()" type="button" value="Hide Grid"/>
<div id="divgrid">
<grid-ui
[grid-columns]="[{'colName':'CustomerCode'},
{'colName':'CustomerName'},{'colName':'CustomerAmount'}]"
[grid-data]="Customers"
(grid-selected)="Select($event)"></grid-ui>
<div>
步骤 4:在组件中导入和使用 Jquery
现在,首先要做的是将 jQuery 导入到您的组件文件中。为此,我们需要使用以下代码。您可以看到 import
语句的使用方式略有不同。我们使用了“*
”和“as
”关键字。“*”表示我们要引用完整的 JQuery 文件,“$
”是我们将在代码中引用 jQuery 语法的别名。
import * as $ from "jquery";
一旦导入了 jQuery,我们现在就可以使用“$
”来执行 jQuery 语法。您可以看到我们创建了一个名为“Fade
”的方法,其中我们引用了 HTML DIV ID 并调用了“fadeToggle
”方法来实现淡入淡出。
import * as $ from "jquery";
export class CustomerComponent {
// Code removed for clarity
Fade(){
$("#divgrid").fadeToggle(3000);
}
}
步骤 5:在 Systemjs.config.js 中进行条目
我们的 JS 文件是使用 SystemJS 模块加载器加载的。因此,我们需要在“Systemjs.config.js”文件中进行条目,说明 jQuery 文件在哪里。
'jquery': '../node_modules/jquery/dist/jquery.js'
★您可以看到,我们已将文件夹路径指定为“dist”。“dist”代表分发文件夹。jQuery 的最终编译副本在此文件夹中,因此我们已指定了它。
现在运行程序并查看输出。如果您单击“Hide”按钮,您应该会看到网格淡出和淡入。
如需进一步阅读,请观看下面的面试准备视频和逐步视频系列。
- Angular 教程面向初学者 | 分步学习 Angular
- Angular 面试问答
- ASP.NET MVC 面试题及答案
- C# 面试问答
- 分步学习 Azure
- SQL Server 分步教程
- RxJS 面试问答
- 1 小时学习 Angular(Angular 9)
- 8 小时分步学习 Angular
历史
- 2017 年 9 月 22 日:初始版本