如何不在 Mithril 中重新渲染整个列表

How to not re-render the whole list in Mithril

我已经使用 React 一段时间了,想尝试一下 Mithril.js。

浏览了文档和示例并喜欢我所看到的内容,所以我说我应该亲自动手并开始编码!

我有一个 smiple API 调用,它接收 JSON 数据,然后输出包含所有项目的 ul 列表。我已经为动画集成了 GSAP TweenMax,我想要实现的目标非常简单——我在加载时淡入所有内容,然后 onclick 我想淡出一个元素并将其从 [=26] 中删除=]/数据。

似乎正在发生的事情是该元素正在淡出,正在重新呈现整个 ul 列表并且该元素保留在 DOM 中且不透明度为 0:

var Item = {
    list: function() {
        return m.request({method: 'GET', url: '/api/items'});
    }
}

var dm = {
    controller: function(data) {                
        var items = Item.list();
        return {
            items: items,
            remove: function(item) {                
                items().data.splice(items().data.indexOf(item), 1);
            }
        }
    },

    view: function(ctrl) {      
        return m('ul', [
            ctrl.items().data.map(function(item, id){
                return m('li',{
                    key: id,
                    config: fadesIn,
                    onclick: fadeOut(ctrl.remove.bind(this, item))
                }, item.title);
            })
        ]);
    }
}

var fadesIn = function(element){
    var tl = new TimelineMax();
    tl.from(element, .5, {opacity: 0});
}

var fadeOut = function(callback) {
    return function(e) {
        m.redraw.strategy('none');
        TweenMax.to(e.target, .5, {opacity: 0, onComplete: function() {
            m.startComputation();           
            callback();         
            m.endComputation();
        }});
    }
}

m.mount(document.getElementById('test'), dm);

我很新..昨天才开始阅读。

让动画库与 Mithril 一起工作可能很棘手。当库操纵 DOM 状态时,与 Mithril 状态的同步可能会中断。

幸运的是,情况并非如此:您缺少的是配置函数的 isInitialized 参数,它仅在第一次调用时为 false。对此进行测试使淡入只发生一次:

var fadesIn = function(element, isInit){
    if(isInit) return;
    var tl = new TimelineMax();
    tl.from(element, .5, {opacity: 0});
}

在这个简单的例子中重绘也可以被简化,我做了一个fiddle有一个工作的例子:

http://jsfiddle.net/ciscoheat/dkyc0ryc/

因为没有 DOM 操作,调用 m.redraw 就足以从 DOM 中删除 div,但您使用 [= 可能是正确的13=] 当事情变得更复杂时。我什至会将 m.startComputation 移动到 TweenMax.to 调用上方以使其更加安全,但如果同时发生许多其他事情,则可能会阻止其他重绘。你必须找到一个平衡点。 :)

我认为在任何情况下都不需要调用 m.redraw.strategy。它主要用于当你不想发生任何事情时(也同步),但是异步动画正在启动,所以它不会有任何效果。

编辑:又发现一个问题,key不能设置为map函数的索引,那么当一个item被移除时它会改变,搞砸了重绘。我已将 fiddle 更新为使用 item.title 作为键。