2

在新的项目中要变更编辑、新增的方式,之前一直是把列表组件和编辑、新增组件放在同一地位来做的,即是兄弟组件的关系,这样虽然可以解决问题,但是每次跳转回列表页面都会重新进行查询,也就是说我们很有可能看不到我们所编辑的那一项,不直观。
所以在新项目中要将编辑、新增组件作为子组件来使用,从而使其更加直观。

状态模式:
状态模式是一种行为设计模式, 让你能在一个对象的内部状态变化时改变其行为, 使其看上去就像改变了自身所属的类一样。

与现实类比:
手机的开机键会根据不同状态完成不同行为。
手机处于解锁状态时,按下按键将熄屏。
手机处于熄屏状态时,按下按键将提示需要解锁。
手机处于电量不足时,按下按键将提示需要充电。

先来说一下标准的状态模式是什么:

流程很简单,就是声明一个状态类然后对其进行实现,然后再在用户所用的类中进行调用,根据不同的状态执行不同的方法。

对于修改编辑组件和列表组件的关系的问题发现在原先项目中已经就可以做到修改之后实时反馈到父组件中并且查询条件不改变。
修改前:
图片.png
修改后:
图片.png
如果我们不想以这种弹出框的形式解决可以进行以下修改:
将弹出框改为div形式,并且当showBatchEdit为false是展示index界面,当showedit为true时只展示edit界面。

<div [formGroup]="queryForm" *ngIf="!showBatchEdit">
//index
...
</div>
<div *ngIf="showBatchEdit">
//edit
  <div class="container-md p-3">
    <app-edit [vehicleBrand]="editVehicleBrand"
              (beSubmit)="onBatchEditSubmit($event)"
              (beClose)="onBatchEditClose()"></app-edit>
  </div>
</div>

但是这样做的话又出现一个新的问题,虽然以弹窗的形式下没有问题,可是改成此样式之后如果我们编辑的是第二页,提交后又会跳会第一页。
打断点进行测试后发现如果使用ngif进行实现的话返回到主页面又会执行一次onPageChange,并且猜测是由于库中函数的原因,再次调用时会直接弹射给index组件page=0,

  <yz-page (changePage)="onPageChange($event)"
           [page]="pageData.number"
           [size]="pageData.size"
           [totalElements]="pageData.totalElements"></yz-page>

进而像下面这样,index接收到弹指

graph TD
    A[index组件接收到弹值page=0] --> B(onPageChange)
    B --> C(reload)
    C --> D(将参数转换为路由参数,更改路由)
    D --> E(触发对路由的订阅)
    E --> F(再次进行分页查询返还首页结果)
ngOnInit(): void {
    console.log('ngoninit');
    . . .
    this.route.queryParams.subscribe((params: { page?: string, size?: string }) => {
    this.vehicleBrandService.page(. . .)
    . . .
        }
    }
  onPageChange(page: number): void {
    console.log('page');
    this.reload({...this.params, ...{page}});
  }
  
reload(params: Params): void {
    console.log(params);
    // 将参数转换为路由参数
    const queryParams = CommonService.convertToRouteParams(params);
    this.router.navigate(['./'],
      {
        relativeTo: this.route,
        queryParams: queryParams,
      }).then();
  }

于是为了进一步确认想法是否正确,又在onSizeChange()处打断点,发现编辑后返回index页面时没有执行,而onPageChange执行了,再一次确认了应该和库中函数设置有关(比如其ngOninit方法中设置了要弹出page=0进行初始化),于是又查询了一下ngif的原理

当NgIf为false时,Angular 从 DOM 中物理地移除了这个元素子树。 它销毁了子树中的组件及其状态,也潜在释放了可观的资源,最终让用户体验到更好的性能。

但是我们现在想要的效果需要不清除DOM来实现,于是再次搜索就发现了[hidden]属性,当其值为true时则隐藏所在对象,但是不将其清除。

[hidden]="showBatchEdit"

问题二:引入lodash中遇到的问题
图片.png
按照官方文档所给只需要像上面这样即可引入lodash库到本地。

var _ = require('lodash');

 const arr = [1,2,3,4,5,6,7,8,9];
_.chunk(arr,2)

然后只需要像上面这样使用即可,但是这样使用后在ng s下会出现报错:
图片.png
require无法正常使用,并询问我们是否需要安装 自定义类型的node。
在安装完 @types/node后在tsconfig中进行配置。

//tsconfig.json

compilerOptions: {
"types": [
      "node"
    ]
}

操作完之后发现ng s下还会报错
图片.png
大概意思是说进行了不合法的操作,之后又尝试在tsconfig.app.json中进行同样的配置再次执行时发现没有报错,并且函数可以正常执行。
图片.png
之后又去看了看两者的区别,发现tsconfig.app.json是继承自tsconfig.json的,也就是说这应该与tsconfig.app.json中新增的配置项有关。

//tsconfig.app.json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",

  },
  "files": [
    "src/main.ts",
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.d.ts"
  ]
}

可以发现多了一个include项,猜测可能和它有关,于是又尝试着在tsconfig.json中加上此配置项再次尝试发现报错消失。又在网上搜寻了一些两者的区别。

tsconfig.app.json 是 Angular 应用程序的配置,

tsconfig.json 用于 IDE 集成

tsconfig.json 作用于全局

lodash相当于对JS函数的拓展,有了更多方法来处理用到的数据如array,number,objects等
lodash中文官方文档


李明
441 声望19 粉丝