正确构建knockoutjs视图模型和服务器调用

时间:2014-01-11 23:57:43

标签: javascript design-patterns knockout.js

我是淘汰赛的新手,今天已经成功地将一个页面与一些绑定和几个ajax调用放在一起。这很有趣!

现在我已经掌握了这些基本功能,我需要考虑接下来要做什么。

情况:

我有一个'设置'页面,上面有4个标签。每个选项卡都有一些输入字段,基本表单元素,但它们都将通过knockout绑定,数据将使用asp.net WebApi和ajax来回传递。

问题是,当我开始在页面上集成其他标签时,如何构建当前的viewmodel以确保我没有碰到某些障碍?

这是我当前的完整视图模型:

function UserSettingsViewModel(apiBaseUrl, userId) {
var self = this;
self.firstName = ko.observable();
self.lastName = ko.observable();
self.primaryEmail = ko.observable();
self.secondaryEmail = ko.observable();
self.addressCity = ko.observable();
self.addressPostalCode = ko.observable();
self.addressCounty = ko.observable();
self.addressCountry = ko.observable();

self.fullName = ko.computed(function () {
    return self.firstName() + " " + self.lastName();
}, this);

$.getJSON(apiBaseUrl + "?userId=" + userId, function (data) {
    alert(JSON.stringify(data));
    self.firstName(data.FirstName);
    self.lastName(data.LastName);
    self.primaryEmail(data.PrimaryEmail);
    self.secondaryEmail(data.SecondaryEmail);
    self.addressCity(data.City);
    self.addressPostalCode(data.PostalCode);
    self.addressCounty(data.County);
    self.addressCountry(data.Country);
});

self.updateName = function () {
    alert('in update name method!');
    $.ajax({
        type: "PUT",
        contentType: "application/json; charset=utf-8",
        url: apiBaseUrl + "?userId=" + userId,
        data: ko.toJSON({
            UserGuid: userId,
            FirstName: self.firstName(),
            LastName: self.lastName(),
            PrimaryEmail: self.primaryEmail(),
            SecondaryEmail: self.secondaryEmail(),
            City: self.addressCity(),
            PostalCode: self.addressPostalCode(),
            County: self.addressCounty(),
            Country: self.addressCountry()
        }),
        dataType: "json",
        success: function (msg) {
            alert('Success');
        },
        error: function (err) {
            alert('Error');
        }
    });
};
}

在视图中我正在做一点点:

ko.applyBindings(new UserSettingsViewModel('@Url.RouteUrl("DefaultApi", 
new { httproute = "httproute", controller = "Settings" })', userId));

同样,我是一个初学者(一年多没碰过这个东西,我当时也不太擅长)。

1 个答案:

答案 0 :(得分:0)

创建一个“顶级”ViewModel并为其创建单独的选项卡ViewModels属性。还要查看映射插件,以减少构造和序列化各个ViewModel所涉及的重复且容易出错的代码量。

您的顶级虚拟机应包含设置页面中observable绑定所使用的template,以便为每个标签的内容选择合适的模板。

更新

“顶级”VM的示例:

var vm={
  userSettings: new UserSettingsViewModel(...),
  readPreferences: new ReadPreferencesViewModel(...),
  sharePreferences: new SharePreferencesViewModel(...),
  activeTab: ko.observable('user-settings')
};
ko.applyBindings(vm);

其中userSettingsreadPreferencessharePreferences是各个标签的虚拟机,activeTab指定用于当前显示的标签的模板ID。

template绑定的Knockout文档非常好。