Knockout.js选项绑定在ViewModel中无法正常工作

时间:2014-08-26 15:55:07

标签: javascript jquery knockout.js

我试图将observabeArray中的值绑定到select元素。这个可观察数组是视图模型的一部分,它与foreach绑定到表。不幸的是它没有用 - 我只有两个空元素。

的JavaScript / jQuery的:

<script>
        // heres what we are going to use for binding parameters
        var Roles = function (name, id) {
            this.Role = name;
            this.id = id;
        };
        var Sexes = function (name, id) {
            this.Sex = name;
            this.id = id;
        }
        function UsersViewModel() {
            //This is array values that I want to bind to select
            rolex: ko.observableArray([
                new Roles("Admin", 3),
                new Roles("User", 1),
                new Roles("Operator", 2)
            ]);
            sexx: ko.observableArray([
                new Sexes("Муж", 1),
                new Sexes("Жен", 0)
            ]);
            var self = this;
            //self.Id = ko.observable();
            //self.Login = ko.observable("");
            //self.Password = ko.observable("");         
            //self.Role = ko.observable();
            //self.Sex = ko.observable();           
            //var user = {
            //    Id: self.Id,
            //    Login: self.Login,
            //    Password: self.Password,
            //    Role: self.Role,
            //    Sex: self.Sex
            //};
            self.user = ko.observable();
            self.users = ko.observableArray();         
            var baseUri = '/api/users';
            $("#adduser").click(function () {
                var json = '{"Login":"' + $("#login").val() + '", "Password":"' + $("#password").val() + '", Sex":' + $("#_sex option:selected").val() + ', "Role":' + $("#_role option:selected").val() + '}';
                $.ajax({
                    url: baseUri,
                    cache: false,
                    type: 'POST',
                    contentType: 'application/json; charset=utf-8',
                    data: json,
                    success: function (data) {
                        $("#notification").text("Пользователь успешно добавлен!");
                        $('#notification').removeClass("hidden");
                        self.users.push(data);
                        setTimeout(function () {
                            $('#notification').addClass("hidden");
                        }, 3000);
                    }
                });
            });
            self.remove = function (user) {
                $.ajax({ type: "DELETE", url: baseUri + '/' + user.Id })
                    .done(function () {
                        $("#notification").text("Пользователь успешно удален!");
                        $('#notification').removeClass("hidden");
                        self.users.remove(user);
                        setTimeout(function () {
                            $('#notification').addClass("hidden");
                        }, 3000);
                    });
            }
            self.update = function (user) {
                $.ajax({ type: "PUT", url: baseUri + '/' + user.Id, data: user })
                .done(function () {
                    $("#notification").text("Изменения сохранены!");
                    $('#notification').removeClass("hidden");
                    setTimeout(function () {
                        $('#notification').addClass("hidden");
                    }, 3000);
                });
            }
            $.getJSON(baseUri, self.users);
        }
        $(document).ready(function () {
            ko.applyBindings(new UsersViewModel());
        })
    </script>


And here is table that show all data including mentioned selects.

HTML:

<table class="pure-table">
                <thead>
                    <tr>
                        <td></td>
                        <td>#</td>
                        <td>Логин</td>
                        <td>Пароль</td>
                        <td>Роль</td>
                        <td>Пол</td>
                    </tr>
                </thead>
                <tbody data-bind="foreach: users">
                    <tr>
                        <td>
                            <input type="button" value="Сохранить" data-bind="click: $root.update" class="pure-button" />
                            <input type="button" value="Удалить" data-bind="click: $root.remove" class="pure-button" />
                        </td>
                        <td data-bind="text: $data.ID"></td>
                        <td>
                            <input type="text" data-bind="value: $data.Login" />
                        </td>
                        <td>
                            <input type="text" data-bind="value: $data.Password" />
                        </td>
                        <td>
                            <select data-bind="options: rolex, optionsText: 'Role'">
                            </select>
                        </td>
                        <td>
                            <select id="sex" data-bind="options: sexx, optionsText: 'Sex'">
                            </select>
                        </td>
                    </tr>
                </tbody>
            </table>

1 个答案:

答案 0 :(得分:2)

需要进行一些更改。首先,你的html需要使用$ root:

<td>
    <select data-bind="options: $root.rolex, optionsText: 'Role'"></select>
</td>
<td>
    <select id="sex" data-bind="options: $root.sexx, optionsText: 'Sex'"></select>
</td>

以下代码有效(请参阅已更改内容的评论):

var Roles = function (name, id) {
    this.Role = name;
    this.id = id;
}; 
var Sexes = function (name, id) {
    this.Sex = name;
    this.id = id;
};

function UsersViewModel() {
    //You should assign self on the first line and use it to assign all properties
    var self = this;

    self.rolex = ko.observableArray([
        new Roles("Admin", 3),
        new Roles("User", 1),
        new Roles("Operator", 2)]);
    self.sexx = ko.observableArray([
        new Sexes("Муж", 1),
        new Sexes("Жен", 0)]);

    self.user = ko.observable();
    self.users = ko.observableArray();

    //You should not add call to $("#adduser").click(...) here, it seems it belongs outside of model

    self.remove = function (user) {
        //Did not test, but it probably works
    };
    self.update = function (user) {
        //Did not test, but it probably works
    };
    return self;
}

// You can use such code to bind the values:
$(function(){
    //Create the model
    var model = new UsersViewModel();

    //Apply bindings
    ko.applyBindings(model);

    //Push the value to the array
    model.users.push({
        Id: 1,
        Login: "Login",
        Password: "Psw",
        Role: 3,
        Sex: 1
    });
});