当前位置: 首页 > Web前端 > HTML

这周遇到的问题

时间:2023-03-28 00:00:56 HTML

首先遇到了一些RXjs的算子,这里简单说一下。第一个是combineLatest。直接翻译就是结合最新的(obserble),所以结合下图就很容易理解了。combineLatest组合所有作为参数传递的Observables的值。这是通过按顺序订阅每个Observable并在任何Observable发出时从每个Observable收集最新值的数组来完成的。因此,如果将nObservables传递给运算符,则返回的Observable将始终发出一个值n的数组,顺序与传递的Observables的顺序相对应(第一个Observable的值在前,依此类推)。让我们用代码再试一次constfirstTimer=Rx.Observable.timer(0,1000);//每秒发出0,1,2...从现在开始constsecondTimer=Rx.Observable.timer(500,1000);//每秒发出0,1,2...后,从现在开始0.5s/logs//[0,0]after0.5s//[1,0]after1s//[1,1]after1.5s//[2,1]after2s从这里我们也可以更深入地实现combineLatest只有当两个observable都触发时才会开始触发。项目中使用了状态管理相关的内容。先简单说一下什么是状态模式。以前也听老师讲过状态模式,但是一直没搞懂状态模式,因为没找到具体的代码。当前项目的state模式可以体现为如下形式,相当于state模式,替代了我们之前使用的service层,state模式的特殊性体现在store的使用上。Store实现了数据直接存储在前台作为缓存。.这么说可能不是很直白,下面加上代码来说明。我们可以简单的认为store只是用来存储/操作一个状态,然后通过继承store类并设置为注入器来实现:比如我们要管理建筑实体@Injectable()exportclassBuildingStoreextendsStore{exportconstBuildingActions={getUnit:'getUnit'}staticunits(state:Unit){returnstate.units;}//添加动作注解来连接动作,以便它们可以被调度调用//我们可以发现这个方法中虽然返回了observable,但是并没有返回数据。这是因为此方法将数据作为状态更新存储在缓存中(store)@Action(taskActions.getUnit)getUnit(state:Building,payload:number|string){returnthis.http.get(xxxurl).pipe(.tap((data)=>{//获取当前状态conststate=this.snapshot;//获取新状态state.units=data.units;//更新状态this.next(state);})}}Then我们可以调用@Injectable()exportclassBuildingComponentextends{...getUnit,1).subscribe(()=>{console.log('unitshavebeenobtained')});//获取此组件中的单位(去商店获取)this.buildingStore.select(BuildingStore.units).subscribe(data=>{console.log("Acquiredunits:");console.log(units);})}另外值得一提的是,如果我们按照上面的代码进行操作,这个.buildingStore.select会被触发两次,第一次是旧数据,第二次是新数据。猜测的过程是:如果我们想从store中获取多种数据,我们可以使用相同的方法来避免获取旧数据文章前面提到的combineLatest是组合使用的,可以保持数据的更新,方便使用。然后说说我这周遇到的一个奇怪的bug:先说问题:当我们更改时间的时候,会弹出一个弹窗。后台发了请求但是前端显示没有实时更新——还是显示11月24日,刷新页面后显示是空的。这个问题一开始我以为是项目本身有bug,但是去掉弹窗操作后发现一切正常。后来想是不是打开弹窗后弹窗组件没有正常销毁导致的。所以在销毁的时候在原组件中dot和alsododot来判断是否影响到各个地方的执行顺序,但是dot之后观察到执行顺序和各个方法都没有影响。而销毁时间也符合预期。后来问了老师才知道,如果在子组件中改变子组件的值,也会出现这个问题。比如我们把XXX对象传递给弹窗组件,如果我们在弹窗组件中改变它,就会出现问题,因为前面说过,对象之间传递的是传递的地址,而angular不建议像这样改变父组件中的对象。后来试了一下,既然直接传递对象有问题,那么深拷贝要传递的对象,把复制的对象传递给弹窗组件应该没问题。试了之后发现还是不行,即使深拷贝之后,还是会出现这样的问题。后来老师经过排查,发现问题还是出在state模式下的store上。例如,我们以建筑为例。我们在父组件中根据buildingId获取单位,然后在子组件中根据buildingId获取单位。这两个地方都可能在获取缓存和执行操作时出现问题,从而导致上述问题。要想更深入地理解问题,就需要进一步了解它的缓存机制——缓存是如何存储的?父组件和子组件缓存是否共享?什么时候应该清除缓存?什么时候缓存会出现问题?这些问题需要在后续的项目中进一步了解。