WEB - 拿图看懂Angular生命周期


前言

为了更简单明了的记住Angular的生命周期,特意整理一张图

红色的被调用一次,绿色的会被调用多次。
这里分为了三个阶段,组件初始化阶段,变化检测,组件销毁。
会在组件初始化后看到组件,在变化检测阶段让属性值和页面展示保持一致。
变化检测中的四个方法和组件初始化中的四个方法是一样的。
一共只有9个方法。

1.首先会调用构造函数

  • ngOnChanges:当一个父组件修改或初始化一个子组件的输入属性的时候被调用
  • ngOnInit:初始化(如果初始化的逻辑需要依赖输入属性,那就一定要写在ngOnInit中,而不要写在构造函数中)
  • ngDoCheck:用来检测
  • ngAfterContentInit:
  • ngAfterContentChecked:
  • ngAfterViewInit
  • ngAfterViewChecked
  • ngDoCheck
  • ngAfterContentChecked
  • ngAfterViewChecked

待续…

WEB - 客户端存储之indexedDB


前言

想必各位前端手们都听过客户端存储,indexedDB就是其中的一种方式,可以作为增强web能力的一种手段,有必要学习了解
一下实用功能。

文章基于《javascript高级程序设计》23章以及MDN技术文档加上一些个人见解和踩坑总结
如有错误欢迎指正。谢谢

简介

IndexedDB是在浏览器中保存结构化数据的一种数据库,对的!你没看错,就是数据库,而且是一种类SQL的结构型数据库,最大
的特色就是用对象来存储数据,容量以及数据存储查询速度远比storage(local/session)好的多,但缺点就是支持程度还不是很好。


使用

由于目前兼容性的问题,所以使用前需要对浏览器提供的API进行兼容:

1
2
3
window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;

1.基本使用模式

打开数据库并且开始一个事务。

  1. 创建一个 object store。
  2. 构建一个请求来执行一些数据库操作,像增加或提取数据等。
  3. 通过监听正确类型的 DOM 事件以等待操作完成。
  4. 在操作结果上进行一些操作(可以在 request 对象中找到)

需要记住的是,任何对indexedDB数据库的操作都是异步进行的,任何操作都会有两个必定的事件权柄:success和error,以下操作均要设置相应的监视事件防止出现错误,由于个人比较懒,在这里展示就不加上了

2. 打开数据库

和mysql/sql数据库的使用一样,indexedDB的使用依旧是从打开数据库开始的,打开方式如下:

1
2
var request = indexedDB.open(DBname, version);
// DBname:数据库名; version:要打开的数据库版本号(可不传值,默认为最新版本)

版本号只能使用int类型,而不能使用浮点数,不然会导致错误

与其它操作不同,open操作特有两个权柄:upgradeneeded(版本更新)和blocked(没有关闭连接尝试连接,(不常用));
依据基本使用模式,正确的打开姿势应为:

1
2
3
4
5
6
7
var request = indexedDB.open(DBname, version);
request.onerror = function() {};
request.onsuccess = funciton() {};
request.onupgradeneeded = function() {};
request.onblocked = function() {};
// 打开的数据库为request触发的成功事件中的event.target.result;
// 以后的操作参照这种方式创建监视事件

注:这里有一个坑,upgradeneeded(版本改动),故名思意是版本改动才会触发的事件,在MDN上的解释是“在数据库第一次被打开时或者当指定的版本号高于当前被持久化的数据库的版本号时,这个版本改动事务将被创建。”,而任何对数据库结构产生改变的操作都应该在这个事件内执行,至于怎么改变数据库结构,请看下文。

3. 删除数据库

1
indexedDB.deleteDatabase(DBname);

4. 对象存储空间

关于对象存储空间,咱们可以把它看成是数据库的一个表,存储空间(表)的使用如下:

打开存储空间

1
var store = db.objectStore(storeName);

创建存储空间

1
2
var store = db.createObjectStore(storeName, {keyPath: keyName, autoIncrement: true});
// 创建存储空间

创建存储空间必须设置keyPath(可以把它看成是存储空间的主键),createObjectStore方法的第二个参数对象就是对keyPath键的配置,配置对象中除了指定键为keyPath,还有另外一个属性autoIncrement,这个属性在MDN文档上的解释是

obj

通俗化讲就是autoIncrement属性是用来设置在被指定为keyPath的键为空时,是否自动生成keyPath值(这里有一点:不启用自动填补keyPath值时,因为keyPath是必须的,如果传入的数据中被指定为keyPath的键为空时,会导致创建存储空间失败,触发error事件)

5. 创建索引

什么是索引:当用户想要通过其它键去访问查询存储空间中的数据时,索引就派上用场了,索引可以看成是存储空间的一个副本,只不过把主键替换成你想要的键,但它并不真实存在,只是给存储空间的访问查询提供了便利。

创建方式:

1
2
3
var store = db.createObjectStore(storeName, {keyPath: keyName, autoIncrement: true};
store.createIndex(indexName, keyName, { unique: false});
// createIndex有三个参数,第一个为索引名,第二个为设置索引的键,第三个为配置对象,unique表示是否允许重复,是否允许重复要根据存储空间的数据而定

填充数据:add方法和put方法,两个方法都是向存储空间中填充数据,但add相当于插入新值,当存储空间中已有相同数据(即keyPath值相同)时会返回错误,put相当于更新原有的值,与add方法相反,put方法会更新已有的数据。

使用方式为:

1
2
3
store.add(obj);
store.put(obj);
// obj为格式正确的数据对象

修改存储空间结构:

对于创建索引和设置keyPath的操作均视为改变数据库结构的操作,因此这些操作必须在upgradeneeded事件下进行,那么问题来了,如果你想重新配置数据库,那么应该怎么去触发这个事件呢?

解决方法有很多种,在这里介绍两种比较实用的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// 第一种,关闭现有数据库连接,打开新版本号的数据库
var request = indexedDB.open(dbName, version),
db;
request.onsuccess = function(event) {
db = event.target.result;
}

// 这里设置延时,因为数据库操作是异步进行的
setTimeOut(function() {
db.close();

request = indexedDB.open(dbName, version + 1);
request.onsuccess = function(event) {
db = event.target.result;
}
requese.onupgradeneeded(event) {
// 这里是更改数据库结构的代码
};

}, 200);


// 第二种,与第一种原理相同,只不过换了另外一种方式
var request = indexedDB.open(dbName, version),
db;
request.onsuccess = function(event) {
db = event.target.result;
}

setTimeOut(function() {
var deleteDbRequest = db.deleteDatabase(dbName);
deleteDbRequest.onsuccess = function (event) {
var openRequest = localDatabase.indexedDB.open(dbName,1);

openRequest.onsuccess = function(event) {
db = openRequest.result;
};
openRequest.onupgradeneeded = function (evt) {
// 这里是更改数据库结构的代码
};
}
}