regularjs / regular

regularjs: a living template engine that helps us to create data-driven component.
http://regularjs.github.io/
MIT License
1.06k stars 149 forks source link

regularJS的track by没起作用 #90

Closed lidong6392 closed 6 years ago

lidong6392 commented 8 years ago

测试版本:0.4.3 测试步骤: 1、先创建一个简单的regular组件

var List = Regular.extend({
    template: `
        <div ref=cnt>
          {#list list as item by item.a}<div>{item.a}</div>{/list}
        </div>
    `
});
var list = new List({
    data: {
        list: [{a: 0}, {a: 1} , {a: 2}, {a: 3}, {a: 4}, {a: 5}]
    }
});

2、给列表中的每个div元素加上一个name属性作为标记

var divs = list.$refs.cnt.getElementsByTagName('div');
for(i = 0, l = list.data.list.length; i < l; i++){
    divs[i].setAttribute('name','test');
}
console.log(list.$refs.cnt.innerHTML);

输出结果:

<!--Regular list--><div name="test">0</div><div name="test">1</div><div name="test">2</div><\div name="test">\3</div><div name="test">4</div><div name="test">5</div>

3、将模型中的数据倒序排列

list.data.list.reverse();
list.$update();
console.log(list.$refs.cnt.innerHTML);

输出结果:

<!--Regular list--><div>5</div><div>4</div><div>3</div><div name="test">2</div><div>1</div><div>0</div>

比较步骤3和步骤2的输出结果,发现只有

2
的name属性还在,其他5个div的name属性都没有了,dom元素应该重新生成了,不是同一个dom元素了。

参考: http://webcode.nie.netease.com/cuz/19/edit?html,js,console,output

leeluolee commented 8 years ago

看了,确实逻辑有问题, 只有 by item_index 是正确的。

lidong6392 commented 8 years ago

还有个问题想咨询下,by item_index只是复用了dom结构,并没有调整dom的顺序,dom里面的html内容还是会被覆盖掉(这个可能没什么影响),但是class名没有随着元素的移动而变化比较奇怪,这样我如果想修改dom相关的东西就必须得把它作为data里面的一个属性了,设计就是这样吗?

var List = Regular.extend({ template: '

{#list list as item by item_index}
{item.a}
{/list}
' }); var list = new List({ data: { list: [{a: 0}, {a: 1} , {a: 2}] } }); var divs = list.$refs.cnt.getElementsByTagName('div'); for(i = 0, l = list.data.list.length; i < l; i++){ divs[i].className='test' + i; divs[i].innerHTML='test' + i; } console.log(list.$refs.cnt.innerHTML); var tmp = list.data.list.pop(); list.data.list.unshift(tmp); list.$update(); console.log(list.$refs.cnt.innerHTML);

第1次输出:

test0
test1
test2

第2次输出:

2
0
1
leeluolee commented 8 years ago

其实如果 不杂糅dom操作进去, 比如class是按插值 数据驱动而来。 class是不会出错的。 by item_index 起初只是为了解决,数据发生改变,但是我不希望直接销毁『块』,而是希望复用原来的『块』。

上面你的例子,表现应该没有错误,因为新的数据 数据为2的item_index确实是0, 所以它复用了第一个『块』。所以目前item_index是没有错误的,它代表的是下标

lidong6392 commented 8 years ago

好的,明白了!谢谢!

leeluolee commented 8 years ago

对, 其它与每个对象相关的 表达式 比如 item.a 这种会引起复用item的顺序的, 虽然输出不会错,但是可能导致『块』是重新生成的, 我v0.4.5会修复