0
  1. 我的 Knockout.js viewModel 有一个更新方法,它绑定到更新按钮的点击事件。单击时,名字和姓氏不包含在 ajax 数据负载中。但是,如果我使这些属性不可观察,那么它们将包含在 ajax 数据播放负载中。有谁知道为什么?

  2. 单选按钮值在 ajax 数据中,但 WebAPI PUT 方法上的模型绑定器看不到更新的值。是因为模型在寻找“真”或“假”值或“1”或“0”时json数据中的“是”和“否”。alertOptInactive属性的数据类型为Nullable。

  3. 成功后,如何刷新绑定到用户可观察数组的表列表?我正在直接调用 self.getByInitial(thisIni),它被定义为 viewModel 中的另一种方法,但它不起作用。getByInitial(thisIni) 在被超链接 DOM 元素触发时确实有效。

谢谢您的帮助。

function viewModel() {
        var baseApiUri = "@Model.apiBaseUrl";

        var self = this;

        /********** view model **********/
        function userViewModel(user) {
            var self = this;
            self.user_ID = user.user_ID;
            self.firstName = ko.observable(user.firstName);
            self.lastName = ko.observable(user.lastName);
            self.long_name = ko.dependentObservable(function () {
                return self.firstName() + " " + self.lastName();
            }, self);
            self.Password = user.Password; //not used but required
            self.Login = user.Login;
            self.dateAdded = user.dateAdded;
            self.email = user.email;
            self.alertOptIn = user.alertOptIn ? "Yes" : "No";
            self.active = user.active ? "Yes" : "No";
        }

        /********** properties **********/
        self.newUser = ko.observable();
        self.userBeforeEdit = ko.observable();
        self.users = ko.observableArray();
        self.user = ko.observable();
        self.operationStatus = ko.observable();

        self.update = function () {
            self.operationStatus("Requesting " + baseApiUri + "/api/user/" + self.user().user_ID + " ...");
            var thisIni = self.user().lastName._latestValue.charAt(0);
            //alert(thisIni);
            $.ajax({
                url: baseApiUri + "/api/user/" + self.user().user_ID,
                cache: false,
                type: 'PUT',
                contentType: 'application/json; charset=utf-8',
                data: JSON.stringify(self.user()),
                success: function () {
                    self.getByInitial(thisIni);
                    self.operationStatus("done");
                }
            })
            .fail(function (xhr, textStatus, err) {
                self.operationStatus(err);

            });
        }

cshtml:

<div id="detailTab">
    <div data-bind="if: user()">
        <input type="hidden" data-bind="text: user().Password"/>
        <div>
            <label for="firstName">First Name</label>
            <input data-bind="value: user().firstName" type="text" title="First Name" />
        </div>

        <div>
            <label for="lastName">Last Name</label>
            <input data-bind="value: user().lastName" type="text" title="Last Name" />
        </div>

        <div>
            <label for="fullName">Full Name</label>
            <input data-bind="value: user().long_name" type="text" title="Full Name" disabled="disabled" />
        </div>

        <div>
            <label for="login">Login</label>
            <input data-bind="value: user().Login" type="text" title="Login" />
        </div>

        <div>
            <label for="dateAdded">Date Added</label>
            <input data-bind="value: user().dateAdded" type="text" title="Date Added" />
        </div>

        <div>
            <label for="email">Email</label>
            <input data-bind="value: user().email" type="text" title="Email" />
        </div>

        <div>
            <label for="emailAlert">Email Alert</label>
            <span><input data-bind="checked: user().alertOptIn" type="radio" title="Send Email Alert" value="Yes" name="alertOptIn"/>Yes</span>
            <span><input data-bind="checked: user().alertOptIn" type="radio" title="No Email Alert" value="No" name="alertOptIn"/>No</span>
        </div>

        <div>
            <label for="accountStatus">Account Status</label>
            <span><input data-bind="checked: user().active" type="radio" title="Active" value="Yes" name="active" />Active</span>
            <span><input data-bind="checked: user().active" type="radio" title="Inactive" value="No" name="active"/>Inactive</span>
        </div>                
        <input type="button" value="Update" data-bind="click: update" />
        <input type="button" value="Cancel" data-bind="click: cancelEdit" />
        <p data-bind="text:operationStatus" class="status"></p>
    </div>
</div>

阿贾克斯请求:

    PUT http://localhost/AppBL/api/user/129 HTTP/1.1
    Accept: */*
    Content-Type: application/json; charset=utf-8
    X-Requested-With: XMLHttpRequest
    Referer: http://localhost/AppUL/Home/UserList
    Accept-Language: en-us
    Accept-Encoding: gzip, deflate
    User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
    Host: localhost
    Content-Length: 220
    Connection: Keep-Alive
    Pragma: no-cache

{"user_ID":129,"Password":"omitted","Login":"myLogin","dateAdded":"2013-08-26T14:09:59","email":"myEmail@mycompany.com",alertOptIn":"Yes","active":"Yes"}
4

2 回答 2

1

你需要这个:

$.ajax({
    url: baseApiUri + "/api/user/" + self.user().user_ID,
    cache: false,
    type: 'PUT',
    contentType: 'application/json; charset=utf-8',
    data: ko.toJSON(self.user()),
    success: function () {
        self.getByInitial(thisIni);
        self.operationStatus("done");
    }
})

ko.toJSON 会将您的 observable 对象转换为普通的旧 JSON 对象,以便您可以将其发布

于 2013-09-06T07:27:33.830 回答
0

关于上面的 Q2,它在我修改了 self.update 方法并将 Yes/No 字符串转换为 true/false 布尔值之后起作用。我想知道是否有更好的方法来做到这一点。

        self.update = function () {
        self.operationStatus("Requesting " + baseApiUri + "/api/user/" + self.user().user_ID + " ...");
        var thisIni = self.user().lastName._latestValue.charAt(0);

        if (self.user().alertOptIn == "Yes")
            self.user().alertOptIn = true;
        else
            self.user().alertOptIn = false;
        if (self.user().active == "Yes")
            self.user().active = true;
        else
            self.user().active = false;

        $.ajax({
            url: baseApiUri + "/api/user/" + self.user().user_ID,
            cache: false,
            type: 'PUT',
            contentType: 'application/json; charset=utf-8',
            data: ko.toJSON(self.user()),
            success: function () {
                self.users.removeAll();
                $.getJSON(baseApiUri + "/api/user?ini=" + thisIni,
                    function (users) {
                        $.each(users, function (index, user) {
                            self.users.push(new userViewModel(user));
                        });
                    });
                self.operationStatus("done");
            }
        })
        .fail(function (xhr, textStatus, err) {
            self.operationStatus(err);

        });
    }
于 2013-09-06T23:00:30.137 回答