在PUT期间不包括ViewMode可观察属性

时间:2013-09-06 07:23:41

标签: javascript jquery ajax knockout.js

  1. 我的Knockout.js viewModel有一个更新方法,它绑定到Update按钮的click事件。单击时,firstName和lastName不包含在ajax数据有效内容中。但是,如果我使这些属性不可观察,那么它们将包含在ajax数据playload中。有谁知道为什么?

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

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

  4. 感谢您的帮助。

    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>
    

    Ajax请求:

        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"}
    

2 个答案:

答案 0 :(得分: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会将您的可观察对象转换为普通的旧JSON,因此您可以将其发布

答案 1 :(得分:0)

上面的第二季度,我修改了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);

        });
    }