【问题标题】:Knockoutjs with jQuery Sortable and jQuery Dialog not working as expected带有 jQ​​uery Sortable 和 jQuery Dialog 的 Knockoutjs 无法按预期工作
【发布时间】:2014-02-21 10:13:49
【问题描述】:

当我添加新页面时,它会添加它们,如果我删除它们,它也可以正常工作,但我有两个问题: * 当我按下编辑时,它允许我使用 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());

【问题讨论】:

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


    【解决方案1】:

    您的主要问题是您使用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>
    

    【讨论】:

    • 是的,你是对的,从那里我完成了保存每个页面数据的代码并在视图中设置更改。谢谢!。
    • 在移动页面和删除后,我仍在尝试解决jQuery Sortable的部分。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-03
    • 1970-01-01
    • 2011-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多