本周遇到的问题

首先是又遇到了一些RXjs操作符,在这里简单的说一下。
首先是 combineLatest。
将其直接翻译过来就是结合最新的(observeble),那么结合一下下面这张图片就很容易理解了。
image.png
combineLatest结合作为参数传递的所有 Observables 的值。这是通过按顺序订阅每个 Observable 并在任何 Observable 发出时从每个 Observable 收集最新值的数组来完成的。因此,如果您将nObservable 传递给运算符,则返回的 Observable 将始终发出一个值数组,n其顺序与传递的 Observable 的顺序相对应(第一个 Observable 的值在第一位,依此类推)。

让我们再结合代码试一下

const firstTimer = Rx.Observable.timer(0, 1000); // emit 0, 1, 2... after every second, starting from now
const secondTimer = Rx.Observable.timer(500, 1000); // emit 0, 1, 2... after every second, starting 0,5s from now
const combinedTimers = Rx.Observable.combineLatest(firstTimer, secondTimer);
combinedTimers.subscribe(value => console.log(value));
// Logs
// [0, 0] after 0.5s
// [1, 0] after 1s
// [1, 1] after 1.5s
// [2, 1] after 2s

从此处我们也能更深刻地认识到,只有两个observble都触发时才会开始触发combineLatest。

项目中 用到了状态管理相关内容,下面来简单地说一下什么是状态模式,之前也有听老师讲过状态模式,但是由于没有找到实际代码所以对状态模式总是不理解。

当前项目的状态模式可以体现为如下形式
未命名文件 (2).jpg

相当于状态模式就是代替了之前我们所用的服务层并且状态模式的特殊之处个人认为就体现在store的使用,store实现了将数据作为缓存直接存储在前台。
可能这么说不是很直接,下面再加上代码来说明一下。
我们目前可以简单地认为一个store只用来存储/操作一种状态,然后通过继承store类并将其设置为注射器来实现:
比如我们想对building实体进行管理

@Injectable()
export class BuildingStore extends Store<Building>{
export const BuildingActions = {
    getUnit: 'getUnit'
}

static units(state: Unit) {
    return state.units;
}

// 添加action注解与actions进行对接,使其可以由dispatch调用
// 我们可以发现此方法中虽然返回了observable但是data并没有返回,这是由于此方法将数据作为状态的更新存进了缓存(store)
@Action(taskActions.getUnit)
getUnit(state: Building, payload: number | string) {
    return this.http.get(xxxurl).pipe(
    .tap((data) => {
        // 获取当前状态
        const state = this.snapshot;
        // 获取新状态
        state.units = data.units;
        // 更新状态
        this.next(state);
        
    })
}


}

然后我们可以在C层中这样调用

@Injectable()
export class BuildingComponent extends {
    . . .
    // 获取building对应的unit到缓存中
    this.buildingStore
        .dispatch(BuildingActions.getUnit, 1)
        .subscribe(() => {
        console.log('已获取units')        
    });

    // 在此组件中获取units(去store中获取)
    this.buildingStore.select(BuildingStore.units)
        .subscribe(data => {
            console.log("获取到的单元:");
            console.log(units);
        })
    
}

此外值得一提的是如果我们照上面代码操作的话this.buildingStore.select会触发两次,第一次是旧数据,第二次是新数据。
猜测其过程为:
未命名文件 (3).jpg

那么如果我们要从store中获取多种数据我们为了避免获取到旧的数据我们就可以和文章前面说到的combineLatest结合使用,从而保持数据的更新并且便于使用。

然后再来说一下本周遇到的一个奇怪的bug:
先说一下问题:
当我们更改时间时会弹出一个弹窗,将弹窗关闭后修改时间没有问题,但是点击右侧X号清空时间虽然向后台发出了请求但是前台显示没有实时更新——仍然是显示11月24,刷新页面后显示为空。
image.png

遇到这个问题期初是认为项目自身就存在的bug,但是将弹窗操作去除后发现一切正常,后来想是不是因为开启弹窗后由于弹窗组件没有正常销毁导致的。

于是在其销毁时进行打点并且在原组件中也进行打点判断各个地方的执行顺序有没有受到影响,但是打点后观察发现执行顺序和各个方法没有任何影响。并且销毁时间也符合预期。

后来询问老师后得知如果在子组件中改变了子组件的值也会发生这样的问题。

比如我们将XXX对象传给了弹窗组件,我们在弹窗组件中对其进行了更改就会发生问题,因为就想之前说到的那样,对象之间的传递都是传的地址,而angular并不推荐像这样改变父组件中的对象。

后来我又尝试既然直接传递对象有问题,那么将要传递的对象深拷贝后将拷贝后的对象传给弹窗组件应该就没问题了。

尝试之后发现还是不行,就算深拷贝后还是会有这样的问题。

后来老师调查后发现问题还是出在了状态模式中的store上。

比如我们还拿building举例,我们在父组件中根据buildingId获取了units,然后在子组件中再根据这个buildingId获取units,这两个地方都是获取缓存并进行操作就可能会出现问题,从而导致上面的问题。

要想更深入了解问题应该就需要进一步了解它缓存的机制——缓存是怎么存的?父组件,子组件缓存共享吗?什么时候清空缓存?缓存在什么情况下会出现问题?
这些问题都需要在之后的项目中进一步了解。

411 声望
14 粉丝
0 条评论
推荐阅读
关于openLADP的进一步了解(@Id与@DnAttribute)
前言:本周主要对gitlabWebhook转github的项目写了写前台部分扫了扫尾,并没有遇到什么问题,所以就上周LDAP中的疑问进行了进一步的了解。承接上文中的问题:@Id和@DnAttribute之间是什么关系。为什么在ldapAdmin...

李明4阅读 481

JavaScript有用的代码片段和trick
平时工作过程中可以用到的实用代码集棉。判断对象否为空 {代码...} 浮点数取整 {代码...} 注意:前三种方法只适用于32个位整数,对于负数的处理上和Math.floor是不同的。 {代码...} 生成6位数字验证码 {代码...} ...

jenemy46阅读 5.8k评论 12

从零搭建 Node.js 企业级 Web 服务器(十五):总结与展望
总结截止到本章 “从零搭建 Node.js 企业级 Web 服务器” 主题共计 16 章内容就更新完毕了,回顾第零章曾写道:搭建一个 Node.js 企业级 Web 服务器并非难事,只是必须做好几个关键事项这几件必须做好的关键事项就...

乌柏木65阅读 6k评论 16

再也不学AJAX了!(二)使用AJAX ① XMLHttpRequest
「再也不学 AJAX 了」是一个以 AJAX 为主题的系列文章,希望读者通过阅读本系列文章,能够对 AJAX 技术有更加深入的认识和理解,从此能够再也不用专门学习 AJAX。本篇文章为该系列的第二篇,最近更新于 2023 年 1...

libinfs39阅读 6.3k评论 12

封面图
从零搭建 Node.js 企业级 Web 服务器(一):接口与分层
分层规范从本章起,正式进入企业级 Web 服务器核心内容。通常,一块完整的业务逻辑是由视图层、控制层、服务层、模型层共同定义与实现的,如下图:从上至下,抽象层次逐渐加深。从下至上,业务细节逐渐清晰。视图...

乌柏木42阅读 7.2k评论 6

CSS 绘制一只思否猫
欢迎关注我的公众号:前端侦探练习 CSS 有一个比较有趣的方式,就是发挥想象,绘制各式各样的图案,比如来绘制一只思否猫?思否猫,SegmentFault 思否的吉祥物,是一只独一无二、特立独行、热爱自由的(&gt;^ω^&lt...

XboxYan42阅读 2.9k评论 14

封面图
从零搭建 Node.js 企业级 Web 服务器(二):校验
校验就是对输入条件的约束,避免无效的输入引起异常。Web 系统的用户输入主要为编辑与提交各类表单,一方面校验要做在编辑表单字段与提交的时候,另一方面接收表单的接口也要做足校验行为,通过前后端共同控制输...

乌柏木33阅读 6.1k评论 9

411 声望
14 粉丝
宣传栏