上一篇利用路由机制传递参数来实作待办事项的编辑功能,除了透过网址路径来传递所需要的参数,还可以在路由定义中透过 resolve
属性物件来指定 Resolve 服务,Angular 会先利用此服务取得资料後,才进行页面元件的载入。
首先,在终端机执行 ng g s task/resolve/task-resolve
来建立 TaskResolveService,并在服务实作 Resolve<Task>
介面。
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve } from '@angular/router';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class TaskResolveService implements Resolve<Task> {
constructor() {}
resolve(route: ActivatedRouteSnapshot): Observable<Task> | Promise<Task> | Task {}
}
接下来,会在 router()
方法实作待办事项资料取得,可以利用传入的 ActivatedRouteSnapshot 物件来取得待办事项编号。
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve } from '@angular/router';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class TaskResolveService implements Resolve<Task> {
constructor(private taskService: TaskRemoteService) {}
resolve(route: ActivatedRouteSnapshot): Observable<Task> {
const id = +route.paramMap.get('id');
return this.taskService.get(id);
}
}
然後在 app-routing.module.ts 中的待办事项编辑路由中,加入 resolve
物件属性,就可以让 Angular 在载入表单页面前取得待办事项资料。
const routes: Routes = [
{ path: '', pathMatch: 'full', redirectTo: 'main' },
{ path: 'main', component: MainPageComponent },
{ path: 'task-list', component: TaskPageComponent },
{ path: 'task-form', component: TaskFormComponent },
{
path: 'task-form/:id',
component: TaskFormComponent,
resolve: {
task: TaskResolveService,
},
},
];
最後,在 task-form.component.ts 中,利用 ActivatedRoute 服务元件内的 data
属性来取得所传入的待办事项资料。
export class TaskFormComponent implements OnInit, OnDestroy {
constructor(private fb: FormBuilder, private router: Router, private route: ActivatedRoute, private taskService: TaskRemoteService) {}
ngOnInit(): void {
this.route.data
.pipe(
map(({ task }: { task: Task }) => task),
filter((task) => !!task),
tap(() => this.tags.clear()),
tap((task) => this.onAddTag(task.tags.length)),
takeUntil(this.stop$)
)
.subscribe((task) => this.form.patchValue(task));
}
}
利用 Chrome DevTool 可以看到目前所开发的程序,会封装成 main.js 载入至用户端。在开发较复杂的 Angular 应用程序时,有时会需要减少运行时所载入的 js 档案大小,以让使用者能更快速的看到页面内容。此时,就可以利用延迟载入 (Lazy Loading) 机制,在使用者选点页面时,才依模组为单位载入对应的 js 档案。
首先,在 Task 模组中加入 task-routing.module.ts 档案,且将与待办事项相关的路由移至此,并在 Task 模组汇入。
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { TaskResolveService } from './resolve/task-resolve.service';
import { TaskFormComponent } from './task-form/task-form.component';
import { TaskPageComponent } from './task-page/task-page.component';
const routes: Routes = [
{ path: 'list', component: TaskPageComponent },
{ path: 'form', component: TaskFormComponent },
{
path: 'form/:id',
component: TaskFormComponent,
resolve: {
task: TaskResolveService,
},
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class TaskRoutingModule {}
接着在 app-routing.module.ts 中利用 loadChildren
设定载入待办事项模组,当路由器导览到 task 路由时,会动态载入 Task 模组,并将 Task 模组内的路由加入配置中。另外,由於路由路径已调整,因此需要变更 app.component.html 中的导览列设定。
const routes: Routes = [
{ path: '', pathMatch: 'full', redirectTo: 'main' },
{ path: 'main', component: MainPageComponent },
{
path: 'task',
loadChildren: () => import('./task/task.module').then((m) => m.TaskModule),
},
];
<nav>
<a [routerLink]="['main']" routerLinkActive="active">首页</a>
<a [routerLink]="['task', 'list']" routerLinkActive="active">待办事项</a>
</nav>
<router-outlet></router-outlet>
需注意一点,由於 Task 模组将会被动态载入,所以在 app.module.ts 中需要移除本来汇入的 Task 模组。利用 Chrome DevTool 可以看到,原来的 main.js 档案大小减少,且在点选待办事项功能时会载入 task-task.module.js。
这一篇利用 resolve 来预先取得页面所需要资料才载入页面元件;并利用延迟载入 (Lazy Loading) 来依模组为单位载入所需要的档案。
<<: 【这些年我似是非懂的 Javascript】Day 29 - 物件 # Part 5 # 特性存取的秘密
>>: 【Day-28】我们是怎麽开始的?:一间传统软件公司从 0 开始建置的 DevOps 文化(工具篇)- 敏捷看板
刚刚是一笔一笔资料带进去慢慢算出来,有另一种方式可以以次把资料全部带入并直接输出结果>>...
介绍 这是 Obsidian 使用教学 — 应用篇的第 4 篇文章。 在 上一篇文章 中我介绍了 B...
前面讲了那麽多,当然在部属unRaid还是要优先考虑设备的选择 当然用淘汰的旧电脑也是可以(小雨这次...
某类型的App价格愈高,使用者平均评价也会有正相关吗? 这是个蛮有趣的议题,照理来说愈贵的app功能...
正在写~ Problem: Need to increase Messenger’s perform...