jrg-project-5
jrg-project-5 copied to clipboard
No Backend 2
cp -r step-4 step-5
cd step-5
# 如果是 Windows 系统,再执行下面两行
rm -rf node_modules
npm i
# 结束 Windows 系统的命令
webpack --watch
# 然后新开一个窗口
数据关联
之前一个任务,虽然我们应该支持注册和登录了,但是用户的数据依然存在于 localStorage,这个任务我们将把数据存到用户名下,也就是让数据与用户关联(associate)起来。
这次任务与之前的任务有一个不同点,那就是我们尝试一些错误的方法。(尝试之后才发现是错的) 为什么要尝试错误的方法呢。 因为你工作中很难一下子就找到正确的方法呀。
保存 todo
之前的任务里,我们是在窗口关闭的时候将数据保存到 localStorage,这次我们想当然地,计划在窗口关闭的时候将数据保存到 LeanCloud。
第一次尝试
我们要用的 API 基本都在《数据存储开发指南 · JavaScript》里。
commit: 页面关闭或刷新时保存数据(看代码时请忽略 bundle.js)
请按照上述代码改写你的代码。
我们刷新页面之后,发现了一个严重的问题。
我们无法调试这段代码!
为什么呢?因为普通的请求如果发出去,我们是可以看见 Network 里面有一个请求的。
但是这次的代码是写在 window.onbeforeunload
里的,所以这个请求一发出,页面就刷新了,Network 也清空了。
怎么办?
这就是真实项目中遇到的问题。
这个时候有两个办法,
-
使用 debugger
我们在 avTodos.save 这句话结束后,写上一句 debugger:
avTodos.save().then(function (todo) { // 成功保存之后,执行其他逻辑. console.log('保存成功'); }, function (error) { // 异常处理 console.error('保存失败'); }); debugger // 👈
然后刷新页面,然后再刷新页面。就发现断点设置成功了。 现在去 Network 看看有没有保存 todos 的请求。 居然还是没有……看了这个时候请求还没有发出。 那么我们到底要怎么看到这个请求呢?
-
使用
preserve log
勾选这个玩意,就能让页面刷新时不清空 Network。 我们删掉 debugger,刷新页面,然后再刷新页面,看看请求有没有发出。 为什么要刷新两次?第一次是让新代码载入页面,第二次是为了触发 beforeunload 事件。
从结果可以看到,AllTodos 保存请求失败了,被
canceled
了。 浏览器为什么会把我的请求取消掉呢? 老司机一想就猜到了:如果一个页面就要死了(刷新就表示不要当前页面了,当前页面可以死了),那么这个页面发出的请求其实就没有任何意义了。既然没有意义,浏览器为什么浪费时间去发这个页面里的请求呢?所以浏览器直接取消了这个请求。
简单来说,那就是:beforeunload 事件里面的所有请求都发不出去,会被取消! 我还从来没有在哪一本书里看到过这个知识点。所以说「实践」是非常重要的。
至此,我们的第一次保存数据的尝试就宣告失败了,因为我们在 beforeunload 事件里不能存将数据存到 LeanCloud。
第二次尝试
一般新人第一次尝试失败就会沮丧了。但是真正的程序员,怎么可能被一次失败打倒。接下来我们尝试第二次。
注意,一旦你推导出 beforeunload 行不通,就不要再死磕它了。你必须推翻以前的思维,「重新思考」。
重新思考我们的目的是什么。
我们是不是希望把用户的数据保存在 LeanCloud?那么我们可不可以在用户对数据进行操作的时候马上就把数据存到 LeanCloud,也就是在每次用户新增、删除 todo 的时候,就发送一个请求。
刷新页面,
- 新增一个 todo,看到保存的请求
- 删除一个 todo,也看到保存的请求
就说明你成功了。
读取 todo
存完数据,就要读数据了。
这个时候我们想想这个功能要怎么做。怎么读数据。
每个 todo 都有一个 id,我可以通过 id 查询到对应的 todo,但是我们怎么知道当前用户有哪些 todo 呢?
好像……没法……知道……
我们目前没有办法知道当前用户有哪些 todo ……
恭喜你,你要返工了。我们保存 todo 的逻辑有问题:没有将用户和 todo 关联起来。
这种现象在实际工作中时有发生(尤其是新手),由于你在开始做项目的时候,没有考虑清楚,最后你发现你的代码根本无法完成需求!
这说明你的思考不够全面。
我怎么才能思考全面呢?
多踩坑。坑踩多了,经验就多了。今天的踩坑,是为了避免明天的踩坑~
重新设计保存逻辑
- todo 存在用户名下
- 只有 todo 所属的用户能读写这些 todo
由于你现在对「ACL(Access Control List)」没有概念,所以你只能听我告诉你,我们可以使用 LeanCloud 提供的 ACL 功能来实现上面两个功能。
翻看《数据存储开发指南 · JavaScript》,找到「角色」这一章节,你会看到一个链接:JavaScript 权限管理使用指南
参考文档,写出下面代码:
commit: 添加访问控制
重新读取 todo
这个时候就要看你读文档的能力了。
我们很容易在文档里找到一个 根据 id 获取数据的 API。
但是很遗憾这不是我们想要的,因为我们根本没有 id 可用。
继续翻文档。
找啊找啊找,你发现有一个「例子」是不需要 id 也能获取数据的,那就是「批量操作」的例子
var query = new AV.Query('Todo');
query.find().then(function (todos) {
todos.map(function(todo) {
todo['status'] = 1;
});
return AV.Object.saveAll(todos);
}).then(function(todos) {
// 更新成功
}, function (error) {
// 异常处理
});
现在还不确定行不行,那就「先试试」。
commit: 获取 User 的 AllTodos
刷新页面,看到控制台拿到数据了!
但是为什么是个数组?
一个用户的 AllTodos 应该只有一个,而不是多个。
原因是,我们存了多个 AllTodos。
我们在用户添加一个 todo 的时候,存了一个 AllTodos; 在用户添加第二个 todo 的时候,又存了一个「新的」AllTodos; 在用户删除一个 todo 的时候,我们又又存了一个「新的」AllTodos……
也就是说,我们的保存逻辑还是有问题。
正确的保存逻辑是:
- 如果发现当前用户没有存过 AllTodos,那么就存一个「新的」AllTodos
- 如果发现当前用户存过 AllTodos,那么就应该更新「之前的」AllTodos
我们怎么知道用户有没有存过 AllTodos 呢?根据 id,有 id 就表示这是数据库中存在的记录,没有 id 就表示是还没保存的记录。
又又又写一次存储逻辑
首先,我们去 LeanCloud 的控制面板把 AllTodos 表清空一下:
然后重写存储逻辑:
commit: 根据 id 选择 save(create) 或者 update
然后我们把一些 alert 去掉,免得惊吓到用户
测试!
接下来我们要测试「不同的用户是否得到不同的 todos」。
- 创建用户 123123
- 添加几个 todo,内容分别是 1、2、3
- 刷新页面,我应该看到 1、2、3 三条 todo
- 登出
- 创建用户 456456
- 登录后,我不应该看到 1、2、3 三条 todo
这样测试,如果成功,就能说明 456456 看不见 123123 创建的 todo 了。
BUG!
测试的时候,发现一个 bug:用户退出 123123 再重新登录 123123,居然看不到自己创建的 todo。
要解决这个 bug,只需要在用户登录后去读取一下 AllTodos 就行了:
commit: 登录后读取 todos
如果你发现不了这个 bug,就只能等你的用户发现这个 bug 了。
那个时候,场面就不太好看了……
致饥人谷学员
我们的 todo 应用就做到这里了,通过这个应用,我们已经大概知道了一个简单的动态页面改怎么做了,接下来我们就开始做在线简历应用了。
请完成上面的所有功能,并且自行测试10遍以上。
自行测试10遍以上! 自行测试10遍以上!
然后把预览链接放到下面。
注意 app id 和 app key
我今天发现有些同学并没有在 LeanCloud 上建立应用,而是直接用了我的 APP ID 和 APP KEY
let APP_ID = '8axnRtGoxCJhEzsvNPEAHnol-gzGzoHsz';
let APP_KEY = '0YH4XkYflb4CUPfA743TGj8G';
我请你们,换成自己的 APP ID 和 APP KEY!
否则哪一天我心情不好把我的应用删了,你的应用就没法读写数据了!
另外,春节快乐!
预览 [代码]https://github.com/lzm320856/vue-text/tree/master/step2) 貌似上次就做完了。。。 另,新春快乐~鸡年大吉吧
@WangXiaoyugg
bug 1: 存储 todo 失败 重现步骤
- 新注册一个用户
- 打开network,添加一个 todo
- 你会在 network 看到 404
@WuHanJun 你的所有请求都重复了两次,应该是你加了 watch 会发一次请求,addTodo 和 removeTodo 的时候又会发一次请求。 解决办法:去掉其中一个。
情感期迷茫?黑人问号???
地址 直接当成一个小作品了~
@ab690257072 BUG:
- 登录 123123
- 添加一个任务 xxx
- 把任务标为已完成
- 刷新页面
- 任务 xxx 依然是未完成! 应该是已完成。
@batman-1 有 bug
- 快速添加几个 todo
- 马上刷新
- 刚才添加的 todo 不见了 ...
@FrankFang 好无语 按了五分钟还没试出这个BUG:joy: 应该是储存发送请求跟网络快慢的关系,我把更新数据放在了清空输入框语句上面,这样应该没问题了,实在不行 再给addTodo再加个几毫秒的延迟,防止快速点击:joy::joy::joy::joy:
@code-zhangrui
那个问号是什么