通过Knockout模板生成的多个嵌套JQuery UI Accordion无法正确绑定

时间:2013-10-06 16:07:03

标签: jquery jquery-ui knockout.js accordion

我正在尝试使用多重嵌套的手风琴控件来使用Knockout,但在添加面板时,通过KO绑定创建的项目不会与手风琴作为新面板绑定。

代码如下所示:


<div data-bind="accordion: {collapsible: true, active: false, heightStyle: 'content'}, template: { name: 'queryTemplate', foreach: children }">
</div>

<script id="queryTemplate" type="text/html">
    <h3>
        <div>
            <a href="#" data-bind="text: id"></a>&nbsp;
            <span data-bind="text: name"></span>&nbsp;
            <button data-bind="click: addNext">Add Next Item</button>
        </div>
    </h3>
    <div >
        <input data-bind="value: name"></input>
        <input data-bind="value: id"></input>
        <button data-bind="click: addSubitem">Add SubItem</button>
        <hr/>
        <div data-bind="accordion: {collapsible: true, active: false, heightStyle: 'content'}, template: { name: 'queryTemplate', foreach: children }">
        </div>
    </div>
</script>

<script>
ko.bindingHandlers.accordion = {
    init: function(element, valueAccessor) {
        var options = valueAccessor() || {};
        setTimeout(function() {
            $(element).accordion(options);
        }, 0);

        //handle disposal (if KO removes by the template binding)
        ko.utils.domNodeDisposal.addDisposeCallback(element, function(){
            $(element).accordion("destroy");
        });
    },
    update: function(element, valueAccessor) {
        var options = valueAccessor() || {},
            existing = $(element).data("accordion");
        //if it has been reinitialized and our model data changed, then need to recreate until they have a "refresh" method
        if (existing) {
           $(element).accordion("destroy").accordion(options);   
           //$(element).accordion("refresh");
        }

    }
};

function Item(id, name, parent) {
    var self = this;
    this.id = ko.observable(id);
    this.name = ko.observable(name);
    this.children = ko.observableArray();
    this.addSubitem = function(){
        self.children.push(new Item(self.children().length + 1, "", this));
    }
    this.parent = ko.observable(parent);
    this.addNext = function(){parent.addSubitem()};
}

var model = new Item(0, "Top");
var tmp = new Item(1, "First", model);
tmp.children.push(new Item(0, "SubItem!", tmp));
model.children.push(tmp);
tmp = new Item(2, "Second", model);
tmp.children.push(new Item(0, "SubItem!", tmp));
model.children.push(tmp);

ko.applyBindings(model);

</script>

我的印象可能是由于我是如何构建模板循环的,但是我的智慧结束了 - 谢谢你,任何人

注:

我会试着澄清我遇到的问题 - (这里是小提琴:http://jsfiddle.net/QChon/aUJFg/4/

手风琴和嵌套手风琴在视图模型之后正确加载(带有“children”数组的Item,它包含Item对象,它应该无限期地继续)。

“添加下一个项目”按钮将一个兄弟添加到当前项目,因此添加到当前的折叠面板,并且“添加子项目”将一个子项添加到当前项目的子项目中,因此在当前项目下添加了一个嵌套的accordeon面板面板。

问题在于,当我单击按钮时,正确的html元素被添加到正确的位置(即,作为标题和内容面板),但jquery类和id不绑定到创建的html控件,因此作为手风琴结构的一部分,不能渲染也不正确。希望有所澄清。

1 个答案:

答案 0 :(得分:0)

问题在于您的自定义绑定功能

您正在通过查看data-accordion属性来检查当前元素是否是手风琴,即使在正确初始化的手风琴上也不存在。其次,即使它发现该属性,它也会尝试重新创建&#39;手风琴在错误的水平上。手风琴的容器类是父的父级,相对于您在update方法中获得的元素。

所以如果你从这个

改变你的功能
var existing = $(element).data("accordion"); 
if (existing)  $(element).accordion("destroy").accordion(options);

到这个

var existing = $(element).parent().parent().hasClass("ui-accordion"); 
if (existing)  $(element).parent().parent().accordion('refresh');

它应该按预期工作。

http://jsfiddle.net/M9222/1/