@Wahson
2017-05-08T14:03:27.000000Z
字数 1355
阅读 1396
前端技术
需求非常简单,实现一个跟Vue.js差不多的框架就行了。
那么既然这样,先看一个Polymer的痛点:
<div>{{obj.a}}</div>
<template is='dom-repeat' items='{{arr}}'>
<li>{{item.ind}}</li>
</template>
上面是
<template>
标签里的代码段,里面包含了一个对obj.a.c的双向绑定,以及对arr数组的绑定。考虑以下情况:当点击按钮(clickHandler
)的时候,我们希望修改obj.a的值,并向arr添加新的数组项,并且希望这些修改反应到页面上。
以下使用polymer的标准方式的实现:
class XElem extends Polymer.Element {
...
static get properties(){
return {
obj:{
type:Object,
value:function(){
return {};
}
},
arr:{
type:Array,
value:function(){
return [];
}
}
};
}
clickHandler(e){
//修改obj.a的值
//方式1:
this.obj.a = 1;
this.notifyPath('obj.a'); //polymer base api
//方式2:
this.set('obj.a',1);
//向arr添加元素
this.arr.push({ind:1});
this.notifySplices('arr'); //polymer base api
}
}
这种方式大家估计应该非常熟悉了。但是这种方式看起来非常麻烦,而且不符合习惯。那么接下来,为了让修改对象和数组变得更加自然一些,我们给Polymer2.0添加了
observable
特性。
先来看一下用法:
class XElem extends Polymer.Element {
...
static get properties(){
return {
obj:{
type:Object,
observable:true
},
arr:{
type:Array,
observable:true
}
};
}
clickHandler(){
//对象
this.obj = {a:{c:1}};
this.obj.a = {c:2};
this.obj.a.c = 3;
//数组
this.arr = [{ind:1}];
//添加元素
this.arr.push({ind:2});
//修改元素
this.arr[0] = {ind:3};
this.arr[0].ind = 4; //不支持
//删除元素
this.arr.splice(2,1)
this.arr.pop();
}
}
用法非常简单:
1、在定义properties的时候,像定义type和value一样,定义observable:true
2、然后修改对象和数组就按照日常操作对象和数组的方式,无需再调用notifyPath和notifySplices了。
nestedObserve特性相关代码:
https://github.com/mrLeung/polymer/commit/e337992abc92bd63c937ffaf98cdb8f0709f17a3
核心代码函数_addObservableEffect