使用jQuery Sortable和jQuery Dialog的Knockoutjs没有按预期工作

时间:2014-01-29 14:27:55

标签: jquery jquery-ui knockout.js jquery-dialog jquery-ui-sortable

当我添加新页面时,它会添加它们,如果我删除它们也可以,但我有两个问题: *当我按下编辑时,它允许我使用jQuery Dialog编辑页面字段,但只有在第一页时才有效。 *当我添加许多页面并使用jQuery Sortable移动它们时(例如,将第三页放在第一页等等)它可以正常工作,但是当我删除其中的任何页面时它会做出奇怪的事情。我调试了它,我正在用JS函数更新模型。这是jsfiddle:http://jsfiddle.net/SuperJohn/LLndg/2/

HTML:

<div style="width: 400px; height: 100%; margin: 10px auto;">
    <div class="pages">
    <ul id="carousel" data-bind="template: { name: 'page-icon', foreach: form.pages }"></ul>
    <ul>
        <li><a href="#" data-bind="click: designer.add.page">New</a></li>
    </ul>
    <script type="text/html" id="page-icon">
        <li>
                <a href="#" data-bind="click: $root.designer.page.id, attr: { title: $data.title }">
        <span data-bind="text: $data.title"></span></a>
        </li>
        </script>
</div>
<div>
    <div id="form" data-bind="template: { name: 'page-template', data: form.pages()[designer.pageId()] }"></div>
</div>
</div>

<script type="text/html" id="page-template">
    <div id="page">
    <h2 id="title" data-bind="text: title"></h2>
    <ul id="page-actions">
        <li><a href="#" id="editPage">Edit</a></li>
    <li><a href="#" data-bind="click: function () { $root.designer.remove.page() }">Remove</a></li>
    </ul>
    <p id="description" data-bind="text: description"></p>
    </div>
<div id="dForm-Page" title="Page">
    <fieldset>
        <legend>General</legend>
    <div>
        <label>Title</label>
        <input type="text" name="dlg-pgTitle" id="dlg-pgTitle" />
    </div>
    <div>
        <label>Instructions</label>
        <textarea name="dlg-pgDescription" id="dlg-pgDescription"></Textarea>
        </div>
        </fieldset>
</div>
</script> 

模型(Java脚本)

function PageForm(id) {
    this.id = ko.observable(id);
this.title = ko.observable('Page Title (pg.' + (id + 1) + ')');
this.description = ko.observable('Instructions or description for the page will appear here.');
}

function DesignerForm(id) {
    this.pages = ko.observableArray([new PageForm(id)]);
}

var ViewModel = function ()
{
    var self = this;
self.form = new DesignerForm(0);

self.designer = {
    "pageId": ko.observable(0),
    "add":
    {
        "page": function ()
    {
        var idx = self.form.pages().length;
        self.form.pages.push(new PageForm(idx));
        self.designer.pageId(idx);
    },
    },
    "remove":
    {
        "page": function ()
    {
        var slfDes = self.designer,
        pg = slfDes.pageId(),
        frmPgs = self.form.pages
        if (pg > 0)
            slfDes.pageId(pg - 1);
        else if (frmPgs().length == 1) {
            slfDes.add.page();
        slfDes.pageId(pg);
        }
        frmPgs.remove(frmPgs()[pg]);
        for (var i = pg; i < frmPgs().length; i++)
        {
            frmPgs()[i].id(i);
        }
    }
    },
    "page": {
        "id": function (data) { self.designer.pageId(data.id()); },
    "next": function () { self.designer.pageId(self.designer.pageId() + 1); },
    "previous": function () { self.designer.pageId(self.designer.pageId() - 1); },
    "nav": function (item)
    {
        // check for knockout bug
        if (item.id() < 999) {
            return 'page-icon';
        } else {
            return 'new-page-icon';
        }
    }
    }
};

$(function() {
    $("#dForm-Page").dialog({
        autoOpen: false,
        height: 300,
        width: 380,
        modal: true,
        buttons: {
            "Save": function() {
            $("#title").text($("#dlg-pgTitle").val());
            $("#description").text($("#dlg-pgDescription").val());
            $(this).dialog("close");    
            },
        Close: function() {
            $(this).dialog("close");
        }
    },
    close: function() {
        $(this).dialog("close");
        }
    });

    $("#editPage").click(function() {
        $("#dlg-pgTitle").val($("#title").text());
    $("#dlg-pgDescription").val($("#description").text());
    $("#dForm-Page").dialog("open");
    });  
});

$(function ()
{
    var pgToMove;
    $("#carousel").sortable({
        start: function (event, ui) {
        pgToMove = ui.item.index();
    },
    update: function (event, ui) {
        var iI = ui.item.index();
        if (iI != pgToMove) {
            var inc = (pgToMove > iI) ? 1 : -1,
            frmPgs = self.form.pages(),
            i;
        for (i = iI; i != pgToMove; i += inc)
        {
            frmPgs[i].id(i + inc);
        }
        frmPgs[i].id(iI);
        frmPgs.sort(function (a, b) { return a.id() - b.id(); });
        }
    }
    });
});
};
ko.applyBindings(new ViewModel());

1 个答案:

答案 0 :(得分:0)

您的主要问题是您正在使用jquery直接修改DOM并使用jquery注册点击事件。

当淘汰赛为你修改DOM时,点击事件被绑定的元素现在已经消失,并被另一个元素取代。

相反,你应该使用淘汰赛点击绑定。 对于任何修改,您应该修改模型并让Knockout为您修改DOM,而不是直接修改DOM。

See this jsfiddle现在使用敲除点击绑定进行编辑。 这段代码还有很多要改变的地方,但我希望它会把你带到正确的方向。

self.designer = {
    "pageId": ko.observable(0),
    "add":
    {
        "page": function ()
        {
            var idx = self.form.pages().length;
            self.form.pages.push(new PageForm(idx));
            self.designer.pageId(idx);
        },
    },
    "edit":
    {
        "page": function ()
        {
            $("#dForm-Page").dialog({
            autoOpen: false,
            height: 300,
            width: 380,
            modal: true,
            buttons: {
                "Save": function() {
                    $("#title").text($("#dlg-pgTitle").val());
                    $("#description").text($("#dlg-pgDescription").val());
                    $(this).dialog("close");    
                },
                Close: function() {
                    $(this).dialog("close");
                }
            },
            close: function() {
                $(this).dialog("close");
            }
        });
                $("#dlg-pgTitle").val($("#title").text());
                $("#dlg-pgDescription").val($("#description").text());
                $("#dForm-Page").dialog("open");
        },
    },        
    "remove":
    {
        "page": function ()
        {
            var slfDes = self.designer,
                pg = slfDes.pageId(),
                frmPgs = self.form.pages
            if (pg > 0)
                slfDes.pageId(pg - 1);
            else if (frmPgs().length == 1) {
                slfDes.add.page();
                slfDes.pageId(pg);
            }
            frmPgs.remove(frmPgs()[pg]);
            for (var i = pg; i < frmPgs().length; i++)
            {
                frmPgs()[i].id(i);
            }
        }
    },
    "page": {
        "id": function (data) { self.designer.pageId(data.id()); },
        "next": function () { self.designer.pageId(self.designer.pageId() + 1); },
        "previous": function () { self.designer.pageId(self.designer.pageId() - 1); },
        "nav": function (item)
        {
            // check for knockout bug
            if (item.id() < 999) {
                return 'page-icon';
            } else {
                return 'new-page-icon';
            }
        }
    }
};

在html中:

<li><a href="#" id="editPage" data-bind="click: $root.designer.edit.page">Edit</a></li>