新增和列表组件关系
之前的项目的设计中,列表组件和新增组件是兄弟组件。
const routes: Routes = [
{
path: '',
component: IndexComponent
},
{
path: 'add',
component: VehicleAddComponent,
},
{
path: 'edit/:id',
component: VehicleEditComponent,
},
];
- 开始时,位于列表组件index。
- 点击新增,跳到add路由,此时加载add组件,并且index组件销毁。
- 新增完成后,需要回跳到index组件。此时需要重新加载index组件,显示第一页的内容。
这样就会导致一个问题,假设原来处在第二页进行编辑或新增,当操作完成之后,并没有回跳到原来的页面。而是加载第一页的内容。
基与这个问题,我们可以尝试把 新增
和 编辑
组件变成 列表
的子组件
同时,我们需要解决 新增或编辑的内容,不能实时的反馈到父组件中
这个问题。
indexComponet:
@Component({
selector: 'app-project',
templateUrl: './index.component.html',
styleUrls: ['./index.component.css']
})
export class IndexComponent implements OnInit {
component = 'index' as 'index' | 'add';
}
index.html:
<app-add *ngIf="component === 'add'" (isFinish)="onAddFinish($event)"></app-add>
<div class="mt-3" *ngIf="component === 'index'">
<button thyButton="success" type="button" (click)="component = 'add'">New Project</button>
// index组件内容
</div>
主要思路就是定义componet变量,当值为'index'时,显示列表内容, 当值为 'add'时,
显示列表组件的内容。
同时,在子组件中设置@Output(), 当创建完成后,弹射该实体值。
AddComponent:
@Component({
selector: 'app-add',
templateUrl: './add.component.html',
styleUrls: ['./add.component.css']
})
export class AddComponent implements OnInit {
@Output()
isFinish = new EventEmitter<Project | null>();
onSubmit(xxx: xxx) {
this.projectService.save(xxx)
.subscribe({
next: project => {
this.notifyService.success('创建成功!');
this.isFinish.emit(project);
},
error: err => {
console.log(err);
}
})
}
/**
* 返回
*/
backWard() {
this.isFinish.emit(null);
}
indexController:
接收弹射值,若弹射实体,表明新增完成,更新到列表中。 若为null, 则表明是返回,返回index界面。
/**
* 新增组件完成后,更新到列表组件中
* @param $event
*/
onAddFinish($event: Project | null) {
if($event) {
this.pageData.content.push($event);
}
this.component = 'index';
}
这样就能够在不重新加载列表组件的情况下,完成新增操作。
NGXS
经过老师的的指导,尝试使用NGXS来进行,状态管理。
Ngxs核心概念:
- Store: 全局状态容器,操作调度程序和选择器
- Actions: 描述要采取的操作及其关联元数据的类
- State: 状态的类定义
- Selects: 状态选择器
经过看官方文档,和查阅相关资料。大概是如下的样子:
一: 注册
- 在 app.module.ts 中注册,NgxsModule.forRoot([ZoosState]) 即可
二:定义Action
新建一个文件action文件。
新建action 定义
import {Project} from '../../../entity/project';
export class AddProject {
static readonly type = '[project] addProject';
constructor(public project: Project) {}
}
三: 新建State
State是定义状态容器的类。
这里定义一个状态,它将监听一个addProject动作。
export interface ProjectModel {
project: Project
}
@State<ProjectModel>({
name: 'project',
defaults: {
project: {} as Project
},
})
@Injectable() // 也可以依赖注入
export class ProjectState {
@Selector()
static getProject(state: ProjectModel) {
return state.project;
}
constructor(private projectService: ProjectService) {}
@Action(AddProject)
addProject(context: StateContext<Project>, action: AddProject) {
const {project} = action;
return this.projectService.saveByToken(project.projectToken).pipe(
tap(project => {
context.setState(project)
})
)
}
}
四: 派发 dispatch
export class AddComponent implements OnInit {
@Select(ProjectState.getProject) project$!: Observable<ProjectModel>;
onSubmit(formGroup: FormGroup) {
const newProject = {
projectToken: formGroup.get(this.formKeys.projectToken)?.value,
} as Project;
this.store.dispatch(new AddProject(newProject))
.pipe(withLatestFrom(this.project$))
.subscribe(([_, project]) => {
console.log(project);
})
}
大致的流程是这样,但可能由于某些地方不太熟悉,写错了,最后数据没能出来。
感想:
因为以前的开发方法不太一样,所以会感觉到有一些难理解。还没有完全理解它的概念的用法。
subscribe的改变
另外值得注意的就是新版本中弃用了该subscribe方法的某些签名,
这种弃用是在 RxJS 6.4 中引入的。
弃用了所有subscribe需要超过 1 个参数的签名,也弃用了仅传递error回调的签名。
目前把参数都写到一个大括号中:
this.labelService.update(this.label.id, newLabel)
.subscribe({
next: label => {
this.notifyService.success(`label edit success`);
},
error: err => {
console.log(err);
this.notifyService.error('请求失败', err);
}
})
类似这种形式。
of([1,2,3]).subscribe({
next: (v) => console.log(v),
error: (e) => console.error(e),
complete: () => console.info('complete')
})
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。