状态模式

发布时间:2022-12-19 09:00

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

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

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

先来说一下标准的状态模式是什么:
状态模式_第1张图片
流程很简单,就是声明一个状态类然后对其进行实现,然后再在用户所用的类中进行调用,根据不同的状态执行不同的方法。

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

//index ...
//edit

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

  

进而像下面这样,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"

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号