通过Knockout模板生成的多个嵌套JQuery UI手风琴无法正确绑定 [英] Multiple nested JQuery UI Accordion generated through Knockout template does not bind correctly

查看:72
本文介绍了通过Knockout模板生成的多个嵌套JQuery UI手风琴无法正确绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使多手风琴控件与Knockout一起使用,但是在添加面板时,通过KO绑定创建的项目不会像新面板那样与手风琴绑定.

I'm trying to get a multiple-nested accordion control to work with Knockout but when adding panels the items created through KO bindings do not bind with the accordion as new panels.

代码如下:

<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>


我的印象可能是由于我如何构建模板循环,但是我很乐意这样做-谢谢任何人


I have the impression it may be due to how I'm building the template loop, but I'm at my wits end with this - thank you, anyone

注意:

我将尝试阐明我遇到的问题-(在小提琴上: http://jsfiddle.net/QChon/aUJFg/4/)

I'll try to clarify the problem I'm having - (here's on fiddle: http://jsfiddle.net/QChon/aUJFg/4/)

按照视图模型(带有子项"数组的Item再次包含Item对象,它应该无限期地进行下去),手风琴和嵌套的手风琴可以正确加载.

The accordion and nested accordions load correctly, following the view model (Item with a "children" array containing again Item objects, which should go on indefinitely).

添加下一个项目"按钮将同级项添加到当前项,从而添加到当前的手风琴面板,添加子项"将子项添加到当前项的子项,从而在当前项下添加一个嵌套的手风琴面板面板.

The "Add Next Item" button adds a sibling to the current Item, and hence to the current accordion panel, and the "Add SubItem" adds a child to the current Item's children, and hence a nested accordeon panel under the current panel.

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

THe problem is that when I click the buttons, the correct html elements are added at the correct places (i.e., as header and as content panel) but the jquery classes and ids are not bound to the created html controls, hence do not render nor behave correctly as part of the accordion structure. Hope that clarifies somewhat.

推荐答案

问题出在您的自定义绑定函数中

The problem is in your custom bindings function

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

You are checking if the current element is an accordion by looking into the data-accordion attribute, which does not exist even on a properly initialized accordion. Secondly even if it finds that attribute it will try to 'recreate' the accordion on the wrong level. The container class of the accordion is the parent's parent, relative to the element that you get in the update method.

因此,如果您从此更改功能

So if you change your function from this

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/

这篇关于通过Knockout模板生成的多个嵌套JQuery UI手风琴无法正确绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆