Angular 前端框架全面分析
Angular 是由Google 维护的开源前端框架。它于2010 年首次发布,最初的版本称为AngularJS。 2016年,团队发布了完全重写的版本,称为Angular 2,后续版本(Angular 4、Angular 5等)统称为Angular。
一、历史背景
1. AngularJS(Angular 1.x)
发布年份:2010年特点:基于MVC(模型-视图-控制器)架构,采用双向数据绑定和依赖注入。局限性:性能瓶颈、可维护性差、学习曲线陡峭。
2. Angular 2+
发布年份:2016 功能:使用基于组件的架构完全重写,并使用TypeScript 开发,以提高性能和可维护性。开发:从Angular 2 开始,Angular 团队每六个月发布一次主要版本。最新版本是Angular 15。
二、技术要点
1. TypeScript
Angular 使用TypeScript 编写,具有静态类型检查和现代JavaScript 功能等优点,有助于提高代码质量和开发效率。
2. 组件化
使用基于组件的开发,您的应用程序被分为独立的、可重用的组件,每个组件都有自己的模板、样式和逻辑。
3. 模块化
使用NgModules 来组织您的代码。 NgModules可以包含组件、指令、管道、服务等,并提供优秀的模块支持。
4. 依赖注入
Angular 提供了强大的依赖注入机制,可以简化服务的创建和管理,并提高代码的可测试性和可维护性。
5. 模板语法
Angular 使用直观的模板语法来定义组件视图,并支持数据绑定、指令、事件绑定等。
6. 路由
Angular 包含一个强大的路由模块,可让您轻松定义应用程序的导航和页面切换。
7. 表单处理
为了适应不同的需求,提供了两种表单处理方式:模板驱动表单和响应式表单。
8. RxJS
Angular 广泛使用RxJS(JavaScript 响应式扩展)来处理异步数据流。这非常适合复杂的数据交互场景。
三、技术难点
1. 学习曲线
Angular 包含很多概念(依赖注入、RxJS、TypeScript 等),因此学习曲线相对陡峭。
2. 性能优化
理解和应用Angular 的变更检测机制和Zone.js 是性能优化的关键,需要一些深度学习。
3. 复杂项目管理
随着项目规模的扩大,挑战变成了如何有效地管理模块、组件、服务等。
四、详细语法和使用规则
1. 组件
从“@angular/core”导入{组件};
@成分({
selecter: \’应用程序根目录\’,
templateUrl: \’./app.component.html\’,
styleUrls: [\’./app.component.css\’]
})
导出类AppComponent {
标题=\’我的角度应用程序\’;
}
2. 模块
从\’@angular/core\’导入{NgModule};
从“@angular/platform-browser”导入{BrowserModule};
从\’./app.component\’导入{AppComponent};
@NgModule({
声明: [
应用程序组件
],
进口产品:[
浏览器模块
],
提供者:[],
bootstrap: [应用程序组件]
})
导出类AppModule { }
3. 数据绑定
插值绑定:{{expression }} 属性绑定:[property]=\’expression\’ 事件绑定:(event)=\’handler\’ 双向绑定:[(ngModel)]=\’property\’
4. 指令
结构指令:*ngIf、*ngFor 属性指令:[ngClass]、[ngStyle]
5. 服务和依赖注入
从\’@angular/core\’ 导入{ Injectable } ;
@Injectable({
提供In: \’root\’,
})
导出类数据服务{
获取数据(){
返回[\’数据1\’,\’数据2\’,\’数据3\’];
}
}
6. 路由
从\’@angular/core\’导入{NgModule};
从\’@angular/router\’ 导入{ RouterModule, Routes };
从\’./home/home.component\’导入{HomeComponent};
导入{ AboutComponent }““打字稿
从\’./about/about.component\’导入{AboutComponent};
const Routes: 路线=[
{ path: \’\’, component: HomeComponent },
{ path: \’关于\’, component: AboutComponent }
];
@NgModule({
import: [RouterModule.forRoot(Root)],
出口:【路由器模块】
})
导出类AppRoutingModule { }
7. 模板驱动表单
表单#form=\’ngForm\’ (ngSubmit)=\’onSubmit(form)\’
输入类型=\’文本\’名称=\’用户名\’需要ngModel
按钮类型=\’提交\’提交/按钮
/形状
8. 响应式表单
从\’@angular/core\’ 导入{ Component, OnInit };
从\’@angular/forms\’ 导入{ FormBuilder、FormGroup、Validators };
@成分({
selector: \’应用程序表单\’,
templateUrl: \’./form.component.html\’
})
导出类FormComponent 实现OnInit {;
form: 表格组;
构造函数(私有fb:表单生成器){}
ngOnInit() {
this.form=this.fb.group({
用户名: [\’\’, 验证器.必填]
});
}
onSubmit() {
console.log(this.form.value);
}
}
表单[formGroup]=\’表单\’ (ngSubmit)=\’onSubmit()\’
输入表单ControlName=\’用户名\’
按钮类型=\’提交\’提交/按钮
/形状
五、底层原理
1. 变更检测机制
Angular 使用Zone.js 捕获异步操作并触发更改检测机制来更新视图。变化检测机制的核心是脏值检测策略。 Angular 将数据的当前值与其之前的值进行比较,以决定是否重新渲染视图。
2. 依赖注入机制
Angular 的依赖注入机制基于提供者和注入器。每个服务、组件等都可以声明依赖关系,Angular 会根据依赖关系图自动注入所需的依赖关系。
3. 编译过程
Angular的编译过程分为两种模式:AOT(Ahead-of-Time)和JIT(Just-in-Time)。
AOT 编译:在构建时编译以生成优化的JavaScript 代码,减少运行时开销并提高应用程序的性能。 JIT编译:在浏览器运行时编译,适合开发阶段使用。
4. 渲染机制
Angular 与React 一样,使用虚拟DOM 进行渲染优化。通过虚拟DOM,Angular 可以高效计算出哪些部分需要更新,减少对实际DOM 的直接操作次数,提高性能。
5. 模块化
Angular的模块系统是通过NgModules实现的。每个NgModule都有自己的执行环境,可以包含组件、指令、管道、服务等。模块化设计有利于代码分离和按需加载,提高应用程序的可维护性和性能。
六、模块化
Angular 是一个强大且全面的前端框架,适合开发大型复杂的Web 应用程序。它使用TypeScript 开发,提供丰富的工具和功能(例如依赖注入、变更检测、模块化和路由),学习曲线陡峭,但在大型项目中表现良好。掌握Angular 的核心概念和原理可以帮助开发人员构建高性能、可维护的Web 应用程序。
当然,我们将介绍更多有关Angular 的内容,包括一些高级功能、最佳实践和常见开发模式。
七、高级特性
1. 懒加载(Lazy Loading)
延迟加载是Angular 提高性能的一个重要特性。延迟加载允许您按需加载模块,而不是在应用程序启动时加载所有模块。
const Routes: 路线=[
{ path: \’home\’, component: home 组件},
{ path: \’about\’,loadChildren: ()=import(\’./about/about.module\’).then(m=m.AboutModule) }
];
2. Angular CLI
Angular CLI 是一个强大的命令行工具,用于初始化、开发、构建和维护Angular 应用程序。
# 安装Angular CLI
npm install -g @angular/cli
# 创建一个新项目
没有新的我的角度应用程序
# 启动开发服务器
服务不好
# 生成组件、服务等
生成组件my-component
3. 国际化(i18n)
Angular 提供内置的国际化支持,可以轻松地将您的应用程序本地化为多种语言。
从“@angular/common”导入{registerLocaleData};
从“@angular/common/locales/fr”导入localeFr。
registerLocaleData(localeFr, \’fr\’);
4. 动态组件加载
在运行时动态加载和渲染组件是Angular 的一项高级功能,适用于需要根据用户交互动态生成内容的场景。
从\’@angular/core\’ 导入{ Component, ComponentFactoryResolver, ViewChild, ViewContainerRef };
@成分({
selector: \’应用程序动态加载器\’,
template: `ng-container #container/ng-container`
})
导出类DynamicLoaderComponent {
@ViewChild(\’container\’, { read: ViewContainerRef, static: true })container: ViewContainerRef;
构造函数(私有解析器: ComponentFactoryResolver){}
loadComponent(component:可选){
const Factory=this.resolver.resolveComponentFactory(组件);
this.container.clear();
this.container.createComponent(工厂);
}
}
5. 服务端渲染(SSR)
Angular Universal 支持服务器端渲染,以提高应用程序的SEO 和首屏加载速度。
# 安装Angular 通用
不要添加@nguniversal/express-engine
# 构建并运行SSR 应用程序
npm 运行build:ssr
npm runserve:ssr
八、最佳实践
1. 代码组织
模块化设计:将应用程序划分为多个功能模块,每个模块负责特定的功能。组件设计:尝试将界面分成独立的组件,以提高可重用性。服务层:将业务逻辑和数据访问层抽象为服务,组件只负责视图逻辑。
2. 性能优化
使用延迟加载:按需加载模块以减少初始屏幕加载时间。避免不必要的更改检测:使用OnPush 更改检测策略来减少不必要的视图更新。异步操作:尝试使用异步操作,例如异步管道、Promises 和Observables。
3. 代码规范
使用TypeScript:充分利用TypeScript 的静态类型检查来提高代码质量。遵循Angular 风格指南:为了保持代码的一致性和可维护性,请遵循官方风格指南。单元和端到端测试:编写单元和端到端测试以确保代码的正确性和稳定性。
九、常见开发模式
1. 智能组件和哑组件
智能组件:负责处理业务逻辑并与服务交互。哑组件:仅负责显示数据和处理简单的用户交互。
//智能组件
@成分({
selecter: \’应用程序智能\’,
template: `app-dumb [data]=\’data\’ (event)=\’handleEvent($event)\’/app-dumb`
})
导出类SmartComponent {
数据=this.dataService.getData();
构造函数(私有dataService: DataService){ }
handleEvent(event: any) { /* 处理事件*/}
}
//哑组件
@成分({
选择器: \’Apridom\’,
template: `div *ngFor=\’数据项\'{{ item }}/div`
})
导出类DumbComponent {
@Input() data: 任何[];
@Output() 事件=new EventEmitterany();
}
2. 状态管理
当然,对于复杂的应用程序,您可以使用状态管理库(例如NgRx)来管理应用程序的状态。接下来,我们将仔细研究Angular 的状态管理、单元测试、与其他技术的集成以及一些高级调试技术。
十、状态管理
1. NgRx
NgRx是Angular中常用的状态管理库,基于Redux架构,提供单状态树、不可变状态和纯函数reducer等功能。
安装 NgRx
不要添加@ngrx/store
@ngrx/不添加效果
状态定义
定义状态接口和初始状态。
//状态.ts
导出接口AppState {
计数:个数;
}
导出常量初始状态: AppState={
计数: 0,
};
Actions
定义动作。
//动作.ts
从\’@ngrx/store\’ 导入{ createAction, props };
导出const 增量=createAction(\'[计数器] 增量\’);
import const decrement=createAction(\'[计数器] 减量\’);
导出常量重置=createAction(\'[计数器]重置\’, props{ count: number }());
Reducer
定义一个减速器。
//减速器.ts
从\’@ngrx/store\’ 导入{ createReducer, on };
从\’./actions\’ 导入{ 递增、递减、重置};
从\’./state\’ 导入{ AppState,InitialState };
const _counterReducer=createReducer(
初始状态,
on(增量, 状态=({ .state, count: state.count + 1 })),
on(递减, state=({ .state, count: state.count – 1 })),
on(重置, (状态, { 计数})=({ .状态, 计数}))
);
导出函数counterReducer(state: AppState | 未定义,action: 操作) {
返回_counterReducer(状态,动作);
}
Store Module
将Store 模块引入到您的应用程序模块中。
从\’@ngrx/store\’ 导入{ StoreModule };
从\’./reducer\’ 导入{ counterReducer };
@NgModule({
进口产品:[
StoreModule.forRoot({ count: counterReducer }),
],
})
导出类AppModule { }
使用 Store
在组件中使用商店。
从“@angular/core”导入{组件};
从\’@ngrx/store\’ 导入{ Store };
从\’./state\’ 导入{ AppState };
从\’./actions\’导入{增量、减量、重置};
@成分({
selector: \’应用程序计数器\’,
模板:`
divCount: {{ 异步}}/div
按钮(点击)=\’increment()\’ 增量/按钮
按钮(点击)=\’减量()\’减量/按钮
按钮(单击)=“重置(0)”重置/按钮
`
})
导出类CounterComponent {
count$=this.store.select(state=state.count);
构造函数(私有商店: StoreAppState){}
增量() {
this.store.dispatch(increment());
}
递减() {
this.store.dispatch(decrement());
}
重置(值:号){
this.store.dispatch(reset({ count: value }));
}
}
2. Akita
Akita 是Angular 的另一个状态管理库,它提供了适合大规模应用程序的灵活状态管理方法。
安装 Akita
不要添加@datorama/akita
定义 Store
从\’@datorama/akita\’ 导入{ Store, StoreConfig };
导出接口AppState {
计数:个数;
}
导出函数createInitialState(): AppState {
返回{
计数: 0,
};
}
@StoreConfig({ name: \’应用程序\’ })
导出类AppStore 扩展StoreAppState {
构造函数(){
超级(创建初始状态());
}
}
使用 Store
从“@angular/core”导入{组件};
小鬼
ort { AppStore } from \’./app.store\’;
@Component({
selector: \’app-counter\’,
template: `
<div>Count: {{ count$ | async }}</div>
<button (click)=\”increment()\”>Increment</button>
<button (click)=\”decrement()\”>Decrement</button>
<button (click)=\”reset()\”>Reset</button>
`
})
export class CounterComponent {
count$ = this.appStore.select(state => state.count);
constructor(private appStore: AppStore) {}
increment() {
this.appStore.update(state => ({ count: state.count + 1 }));
}
decrement() {
this.appStore.update(state => ({ count: state.count – 1 }));
}
reset() {
this.appStore.reset();
}
}
十一、单元测试
Angular 提供了强大的单元测试支持,使用 Karma 和 Jasmine 进行测试。
1. 设置测试环境
Angular CLI 自动生成的项目已经配置好了 Karma 和 Jasmine,无需额外配置。
2. 编写测试当然,我将继续深入探讨 Angular 的单元测试、与其他技术的集成、以及一些高级调试技巧。
十一、单元测试(继续)
2. 编写测试
组件测试
使用 TestBed 创建组件并进行测试:
import { ComponentFixture, TestBed } from \’@angular/core/testing\’;
import { CounterComponent } from \’./counter.component\’;
describe(\’CounterComponent\’, () => {
let component: CounterComponent;
let fixture: ComponentFixture<CounterComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ CounterComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(CounterComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it(\’should create\’, () => {
expect(component).toBeTruthy();
});
it(\’should increment count\’, () => {
component.increment();
expect(component.count).toBe(1);
});
it(\’should decrement count\’, () => {
component.decrement();
expect(component.count).toBe(-1);
});
it(\’should reset count\’, () => {
component.reset(0);
expect(component.count).toBe(0);
});
});
服务测试
测试服务时,使用 TestBed 配置提供者:
import { TestBed } from \’@angular/core/testing\’;
import { DataService } from \’./data.service\’;
describe(\’DataService\’, () => {
let service: DataService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(DataService);
});
it(\’should be created\’, () => {
expect(service).toBeTruthy();
});
it(\’should get data\’, () => {
const data = service.getData();
expect(data).toEqual([\’item1\’, \’item2\’]);
});
});
3. 运行测试
使用 Angular CLI 运行测试:
ng test
十二、与其他技术的集成
1. 与后端 API 的集成
使用 Angular 的 HttpClient 模块来与后端 API 进行通信。
安装 HttpClient 模块
import { HttpClientModule } from \’@angular/common/http\’;
@NgModule({
imports: [ HttpClientModule ],
})
export class AppModule { }
创建服务
import { Injectable } from \’@angular/core\’;
import { HttpClient } from \’@angular/common/http\’;
import { Observable } from \’rxjs\’;
@Injectable({
providedIn: \’root\’,
})
export class ApiService {
constructor(private http: HttpClient) {}
getData(): Observable<any> {
return this.http.get(\’https://api.example.com/data\’);
}
postData(data: any): Observable<any> {
return this.http.post(\’https://api.example.com/data\’, data);
}
}
使用服务
import { Component, OnInit } from \’@angular/core\’;
import { ApiService } from \’./api.service\’;
@Component({
selector: \’app-data\’,
template: `<div *ngFor=\”let item of data\”>{{ item }}</div>`,
})
export class DataComponent implements OnInit {
data: any;
constructor(private apiService: ApiService) {}
ngOnInit() {
this.apiService.getData().subscribe(data => this.data = data);
}
}
2. 与第三方库的集成
Angular 可以轻松集成第三方库,如 RxJS、Lodash 等。
使用 RxJS
import { of } from \’rxjs\’;
import { map } from \’rxjs/operators\’;
const observable = of(1, 2, 3).pipe(
map(x => x * 2)
);
observable.subscribe(value => console.log(value)); // 输出 2, 4, 6
使用 Lodash
import * as _ from \’lodash\’;
const array = [1, 2, 3, 4];
const doubled = _.map(array, x => x * 2);
console.log(doubled); // 输出 [2, 4, 6, 8]
当然,我将继续介绍更多关于 Angular 的内容,包括高级调试技巧、动画、表单处理、以及一些常见的开发工具和资源。
十三、高级调试技巧(继续)
2. 使用 Debug 模式
启用 Debug 模式
在开发过程中,可以启用 Angular 的 Debug 模式,以便在控制台中查看详细的调试信息。
import { enableProdMode } from \’@angular/core\’;
if (environment.production) {
enableProdMode();
} else {
// 开发模式下启用调试信息
import(\’zone.js/plugins/zone-error\’); // Included with Angular CLI.
}
3. Angular 调试工具
使用 ng.probe
在浏览器控制台中,可以使用 ng.probe 方法来访问组件实例和调试信息。
// 获取组件实例
const component = ng.probe(document.querySelector(\’app-root\’)).componentInstance;
console.log(component);
使用 Augury
Augury 是一个用于调试 Angular 应用的 Chrome 扩展,提供组件树、依赖注入、路由等信息的可视化展示。
安装 Augury
在 Chrome 浏览器中,访问 Augury 页面并安装扩展。
使用 Augury
打开 Chrome 开发者工具,切换到 Augury 标签,可以查看组件树、依赖关系等信息。
十四、动画
Angular 提供了强大的动画支持,通过 Angular Animations 模块可以实现复杂的动画效果。
1. 安装 Angular Animations
import { BrowserAnimationsModule } from \’@angular/platform-browser/animations\’;
@NgModule({
imports: [BrowserAnimationsModule],
})
export class AppModule {}
2. 定义动画
使用 trigger、state、style、transition 和 animate 来定义动画。
import { trigger, state, style, transition, animate } from \’@angular/animations\’;
@Component({
selector: \’app-animated\’,
template: `
<div [@fadeInOut]=\”\’in\’\”>Fade In Out Animation</div>
<button (click)=\”toggleState()\”>Toggle State</button>
`,
animations: [
trigger(\’fadeInOut\’, [
state(\’in\’, style({ opacity: 1 })),
transition(\’:enter\’, [
style({ opacity: 0 }),
animate(600)
]),
transition(\’:leave\’, [
animate(600, style({ opacity: 0 }))
])
])
]
})
export class AnimatedComponent {
state = \’in\’;
toggleState() {
this.state = this.state === \’in\’ ? \’out\’ : \’in\’;
}
}
十五、表单处理
Angular 提供了两种表单处理方式:模板驱动表单和响应式表单。
1. 模板驱动表单
模板驱动表单使用 Angular 的指令和模板语法来处理表单。
import { FormsModule } from \’@angular/forms\’;
@NgModule({
imports: [FormsModule],
})
export class AppModule {}
<!– template-driven-form.component.html –>
<form #form=\”ngForm\” (ngSubmit)=\”onSubmit(form)\”>
<label for=\”name\”>Name:</label>
<input type=\”text\” id=\”name\” name=\”name\” ngModel>
<button type=\”submit\”>Submit</button>
</form>
// template-driven-form.component.ts
import { Component } from \’@angular/core\’;
@Component({
selector: \’app-template-driven-form\’,
templateUrl: \’./template-driven-form.component.html\’
})
export class TemplateDrivenFormComponent {
onSubmit(form: any) {
console.log(\’Form Data:\’, form.value);
}
}
2. 响应式表单
响应式表单使用 FormBuilder 和 FormGroup 来处理表单。
import { ReactiveFormsModule, FormBuilder, FormGroup } from \’@angular/forms\’;
@NgModule({
imports: [ReactiveFormsModule],
})
export class AppModule {}
<!– reactive-form.component.html –>
<form [formGroup]=\”form\” (ngSubmit)=\”onSubmit()\”>
<label for=\”name\”>Name:</label>
<input type=\”text\” id=\”name\” formControlName=\”name\”>
<button type=\”submit\”>Submit</button>
</form>
// reactive-form.component.ts
import { Component, OnInit } from \’@angular/core\’;
import { FormBuilder, FormGroup } from \’@angular/forms\’;
@Component({
selector: \’app-reactive-form\’,
templateUrl: \’./react
### 2. **响应式表单**
响应式表单使用 `FormBuilder` 和 `FormGroup` 来处理表单。
#### 创建表单
“`typescript
import { Component, OnInit } from \’@angular/core\’;
import { FormBuilder, FormGroup, Validators } from \’@angular/forms\’;
@Component({
selector: \’app-reactive-form\’,
templateUrl: \’./reactive-form.component.html\’
})
export class ReactiveFormComponent implements OnInit {
form: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.form = this.fb.group({
name: [\’\’, Validators.required],
email: [\’\’, [Validators.required, Validators.email]],
password: [\’\’, [Validators.required, Validators.minLength(6)]]
});
}
onSubmit() {
if (this.form.valid) {
console.log(\’Form Data:\’, this.form.value);
} else {
console.log(\’Form is invalid\’);
}
}
}
表单模板
<form [formGroup]=\”form\” (ngSubmit)=\”onSubmit()\”>
<div>
<label for=\”name\”>Name:</label>
<input type=\”text\” id=\”name\” formControlName=\”name\”>
<div *ngIf=\”form.get(\’name\’).invalid && form.get(\’name\’).touched\”>
Name is required
</div>
</div>
<div>
<label for=\”email\”>Email:</label>
<input type=\”email\” id=\”email\” formControlName=\”email\”>
<div *ngIf=\”form.get(\’email\’).invalid && form.get(\’email\’).touched\”>
Enter a valid email
</div>
</div>
<div>
<label for=\”password\”>Password:</label>
<input type=\”password\” id=\”password\” formControlName=\”password\”>
<div *ngIf=\”form.get(\’password\’).invalid && form.get(\’password\’).touched\”>
Password must be at least 6 characters long
</div>
</div>
<button type=\”submit\”>Submit</button>
</form>
十六、路由
Angular 的路由模块允许你在应用中定义导航路径。
1. 设置路由
配置路由
import { NgModule } from \’@angular/core\’;
import { RouterModule, Routes } from \’@angular/router\’;
import { HomeComponent } from \’./home/home.component\’;
import { AboutComponent } from \’./about/about.component\’;
const routes: Routes = [
{ path: \’\’, component: HomeComponent },
{ path: \’about\’, component: AboutComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
导航链接
<nav>
<a routerLink=\”/\”>Home</a>
<a routerLink=\”/about\”>About</a>
</nav>
<router-outlet></router-outlet>
2. 路由守卫
路由守卫用于保护路由,确保用户具有访问权限。
import { Injectable } from \’@angular/core\’;
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from \’@angular/router\’;
import { AuthService } from \’./auth.service\’;
@Injectable({
providedIn: \’root\’
})
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): boolean {
if (this.authService.isLoggedIn()) {
return true;
} else {
this.router.navigate([\’/login\’]);
return false;
}
}
}
使用路由守卫
const routes: Routes = [
{ path: \’\’, component: HomeComponent },
{ path: \’about\’, component: AboutComponent, canActivate: [AuthGuard] }
];
十七、国际化
Angular 提供了内置的国际化支持,用于多语言应用程序。
1. 准备翻译文件
创建翻译文件 messages.xlf:
<?xml version=\”1.0\” encoding=\”UTF-8\” ?>
<xliff version=\”1.2\”>
<file source-language=\”en\” datatype=\”plaintext\” original=\”ng2.template\”>
<body>
<trans-unit id=\”homeTitle\” datatype=\”html\”>
<source>Home</source>
<target>Accueil</target>
</当然,我将继续介绍更多关于 Angular 的内容,包括国际化的详细步骤、服务端渲染、以及一些常用的开发工具和资源。
## 十七、国际化(继续)
### 1. **准备翻译文件**
创建翻译文件 `messages.xlf`:
“`xml
<?xml version=\”1.0\” encoding=\”UTF-8\” ?>
<xliff version=\”1.2\”>
<file source-language=\”en\” datatype=\”plaintext\” original=\”ng2.template\”>
<body>
<trans-unit id=\”homeTitle\” datatype=\”html\”>
<source>Home</source>
<target>Accueil</target>
</trans-unit>
<trans-unit id=\”aboutTitle\” datatype=\”html\”>
<source>About</source>
<target>À propos</target>
</trans-unit>
</body>
</file>
</xliff>
2. 配置 Angular
在 angular.json 中添加国际化配置:
{
\”$schema\”: \”./node_modules/@angular/cli/lib/config/schema.json\”,
\”projects\”: {
\”your-project-name\”: {
\”i18n\”: {
\”sourceLocale\”: \”en\”,
\”locales\”: {
\”fr\”: \”src/locale/messages.fr.xlf\”
}
},
…
}
}
}
3. 标记可翻译文本
使用 Angular 内置的 i18n 属性标记可翻译的文本:
<h1 i18n=\”homeTitle\”>Home</h1>
<p i18n=\”aboutTitle\”>About</p>
4. 构建多语言版本
使用 Angular CLI 构建多语言版本:
ng build –localize
十八、服务端渲染(SSR)
Angular Universal 是一个用于实现 Angular 应用服务端渲染的库。
1. 安装 Angular Universal
ng add @nguniversal/express-engine
2. 更新应用模块
更新 app.server.module.ts 以适配服务端渲染:
import { NgModule } from \’@angular/core\’;
import { ServerModule } from \’@angular/platform-server\’;
import { AppModule } from \’./app.module\’;
import { AppComponent } from \’./app.component\’;
@NgModule({
imports: [
AppModule,
ServerModule
],
bootstrap: [AppComponent]
})
export class AppServerModule {}
3. 更新服务器文件
配置 server.ts 文件以启动 Express 服务器:
import \’zone.js/node\’;
import { ngExpressEngine } from \’@nguniversal/express-engine\’;
import * as express from \’express\’;
import { join } from \’path\’;
import { APP_BASE_HREF } from \’@angular/common\’;
import { existsSync } from \’fs\’;
import { AppServerModule } from \’./src/main.server\’;
// The Express app is exported so that it can be used by serverless Functions.
export function app(): express.Express {
const server = express();
const distFolder = join(process.cwd(), \’dist/your-project-name/browser\’);
const indexHtml = existsSync(join(distFolder, \’index.original.html\’)) ? \’index.original.html\’ : \’index\’;
server.engine(\’html\’, ngExpressEngine({
bootstrap: AppServerModule,
}));
server.set(\’view engine\’, \’html\’);
server.set(\’views\’, distFolder);
// Serve static files from /browser
server.get(\’*.*\’, express.static(distFolder, {
maxAge: \’1y\’
}));
// All regular routes use the Universal engine
server.get(\’*\’, (req, res) => {
res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
});
return server;
}
function run(): void {
const port = process.env.PORT || 4000;
// Start up the Node server
const server = app();
server.listen(port, () => {
console.log(`Node Express server listening on http://localhost:${port}`);
});
}
// Webpack will replace \’require\’ with \’__webpack_require__\’
// \’__non_webpack_require__\’ is a proxy to Node \’require\’
declare const __non_webpack_require__: NodeRequire;
const mainModule = __non_webpack_require__.main;
const moduleFilename = mainModule && mainModule.filename || \’\’;
if (moduleFilename === __filename || moduleFilename.includes(\’iisnode\’)) {
run();
}
export * from \’./src/main.server\’;
4. 运行 SSR
使用 Angular CLI 构建和运行 SSR 应用:
npm run build:ssr
npm run serve:ssr
#以上关于全面分析一下前端框架Angular的来龙去脉,分析angular的技术要点和难点,以及详细的语法和使用规则,底层原理的相关内容来源网络仅供参考,相关信息请以官方公告为准!
原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/91815.html