将Knockout.JS视图模型绑定到jQuery对话框

时间:2013-07-11 16:24:25

标签: javascript jquery knockout.js

我有一个jQuery模式对话框,我想在其中传递Knockout视图模型中的数据。该对话框工作正常 - 但是,下面的代码被破坏了。

理想情况下,我希望能够单击触发模式对话框的URI,并让对话框加载Knockout视图模型中的数据。任何帮助将不胜感激。

加价:

<a href="#" id="listNames">List Names</a>

<div  id="listNames"  data-bind="dataModel: { autoOpen: false, modal: true }">
<div> 
    <form action=''>
        <p>You have added <span data-bind='text: name().length'>&nbsp;</span> 
            person(s)</p>
        <table data-bind='visible: name().length > 0'>
            <thead>
                <tr><th>Select</th>
                    <th>Name</th>
                    <th>Age</th>
                    <th />
                </tr>
            </thead>
            <tbody data-bind='foreach: metrics'>
                <tr>
                    <td><input type="checkbox" /></td>
                    <td><span data-bind='text: name' >&nbsp;</span></td>
                    <td><span  data-bind='text: age'>&nbsp;</span></td> 
                </tr>
            </tbody>
        </table>
    </form>
  </div>
</div>

视图模型:

var dataModel = function (edata) {
    var self = this;
    self.edata = ko.observableArray(edata);

    self.addname = function () {
        self.edata.push({
            name: "",
            age: ""
        });
    };

    self.removename = function (name) {
        self.edata.remove(name);
    };

    self.save = function (form) {
        alert("Could now transmit to server: " 
              + ko.utils.stringifyJson(self.edata));
        // To actually transmit to server as a regular form post, write this: 
        // ko.utils.postJson($("form")[0], self.edata);
    };
};

var viewModel = new dataModel([
    { name: "Jack", age: "41" },
    { name: "Jill", age: "33" }
]);
ko.applyBindings(new viewModel);

jQuery对话:

$("#listNames, ").dialog({
    autoOpen: false,
    width: 300,
    modal: true,
    buttons: {
        "OK": function () {
            $(this).dialog("destroy");
        },
        Cancel: function () {
            $(this).dialog("close");
        }
    }
});

$("#openList")
    .click(function () {
        $("#listNames").dialog("open");
    });

1 个答案:

答案 0 :(得分:2)

您发布的代码中存在一些错误。 我在这里有一个工作版本:http://jsfiddle.net/uFgz8/1/

以下是HTML:

        <a href="#" data-bind="click: $root.openDialog"> Open dialog </a> //you had 2 elements with the same ID, I removed the ID on the link and bound it to a method in the view model

    <div id="listNames">   <div>
            <form action=''>
                <p>You have added <span data-bind='text: name.length'>&nbsp;</span> person(s)</p> // name item is not observable, so you cannot use name().length
                <table data-bind='visible: name.length > 0'> // same remark for name
                    <thead>
                        <tr>
                            <th>Select</th>
                            <th>Name</th>
                            <th>Age</th>
                            <th />
                        </tr>
                    </thead>
                    <tbody data-bind='foreach: edata'>
                        <tr>
                            <td>
                                <input type="checkbox" />
                            </td>
                            <td><span data-bind='text: name'>&nbsp;</span>

                            </td>
                            <td><span data-bind='text: age'>&nbsp;</span>

                            </td>
                        </tr>
                    </tbody>
                </table>
            </form>
        </div>
    </div>

JS:

$("#listNames").dialog({
    autoOpen: false,
    width: 300,
    modal: true,
    buttons: {
        "OK": function () {
            // do something
            $(this).dialog("close"); // I replaced destroy by close, so it can be opened after ok has been clicked
        },
        Cancel: function () {
            $(this).dialog("close");
        }
    }
});

var dataModel = function (edata) {
    var self = this;
    self.edata = ko.observableArray(edata);

    self.addname = function () {
        self.edata.push({
            name: "",
            age: ""
        });
    };

    self.openDialog = function () {
        $("#listNames").dialog("open");
    };

    self.removename = function (name) {
        self.edata.remove(name);
    };

    self.save = function (form) {
        alert("Could now transmit to server: " + ko.utils.stringifyJson(self.edata));
        // To actually transmit to server as a regular form post, write this: ko.utils.postJson($("form")[0], self.edata);
    };
};

var viewModel = new dataModel([{
    name: "Jack",
    age: "41"
}, {
    name: "Jill",
    age: "33"
}]);

ko.applyBindings(viewModel); // you have created a variable viewModel with data, but you bound ko with a new object of type viewModel, you must either call ko with viewModel you created, or inline the creation of a new "dataModel"

编辑:我在我的更改中添加了一些评论

编辑2:我更新了指向jsfiddle的链接以获得正确的版本;)