【问题标题】:KendoUI - UI not refreshed after extracting repeating functionsKendoUI - 提取重复功能后 UI 未刷新
【发布时间】:2015-01-31 14:09:45
【问题描述】:

我有一个视图模型,它有几个集合属性和一些重复的逻辑。 我需要能够添加一个新的空对象,删除一个对象,并确保每个集合至少有一个对象,如果它是唯一的对象,应该禁用“删除”按钮。

为了提取这些常用函数,我扩展了 kendo.data.ObservableArray:

function addEmpty() {
  this.push({});
}

function hasMoreThanOne {
  return this.length > 1;
}

var CoolObservableArray = kendo.data.ObservableArray.extend({
  init: function(data) {
    kendo.data.ObservableArray.fn.init.call(this, data);

    this.addEmpty = addEmpty.bind(this);
    this.hasMoreThanOne = hasMoreThanOne.bind(this);
  }
});

问题在于hasMoreThanOne 函数。当我创建一个包含单个元素的数组时,“删除”按钮被禁用 - 没关系 - 但是当我添加新元素时,它不会被启用。

要刷新 UI 需要调用剑道的 get 函数,但它需要一个引用属性名称的参数,这对于 CoolObservableArray 的每个实例都会有所不同,所以我需要为每个集合编写重复函数,例如deleteXXXEnableddeleteYYYEnabled等。如何避免?

这里是问题再现的小提琴:http://dojo.telerik.com/AFOMa/2

【问题讨论】:

    标签: javascript kendo-ui observable kendo-mvvm kendo-observable


    【解决方案1】:

    源绑定仅呈现您添加到ObservableArray 的新对象,因为通知绑定的更改事件仅指示添加了新项目。

    您可以通过手动触发更改事件来强制源绑定重新渲染整个视图:

    var CoolObservableArray = kendo.data.ObservableArray.extend({
        init: function (data, type) {
            kendo.data.ObservableArray.prototype.init.call(this, data, type);
    
            this.addEmpty = addEmpty.bind(this);
            this.deleteObject = deleteObject.bind(this);
            this.hasMoreThanOne = hasMoreThanOne.bind(this);    
            this.bind("change", function (e) {      
                if (e.action === "add" || e.action === "remove") {
                    var that = this;
    
                    // trigger another change which is not an "add" 
                    // or "remove" or "itemchange" action
                    setTimeout(function () {
                        that.trigger("change");
                    }, 5);   
                }
            });  
        }
    });
    
    var viewModel = kendo.observable({
        wares: new CoolObservableArray([
            {title: "hampton sofa", price: 989}
        ])
    });
    
    kendo.bind("#waresWrapper", viewModel);
    

    (updated demo)

    【讨论】:

    • Lars,非常感谢,这就是我想要的。但是你能解释一下,为什么我需要setTimeout?如果我省略它,则第一次会添加两次新元素,然后像往常一样添加新元素。为什么会这样?
    • @nativehr 如果没有超时,首先执行第一个更改事件,这会导致整个视图重新渲染(包括添加的元素)。然后绑定通过 e.type === "add" 获得另一个更改事件,并呈现另一个新元素。所以你最终会得到 2 个额外渲染的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-02
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 2019-04-27
    相关资源
    最近更新 更多