将 knockoutjs 视图模型传递给多个 ajax 调用
Posted
技术标签:
【中文标题】将 knockoutjs 视图模型传递给多个 ajax 调用【英文标题】:Passing knockoutjs view model to multiple ajax calls 【发布时间】:2012-10-02 13:47:03 【问题描述】:我有一个函数可以进行 ajax 调用以获取初始数据并将其保存到视图模型。然后,我将返回的视图模型(对数据进行字符串化)传递给另一个函数,该函数进行另一个 ajax 调用,依此类推。每个函数都绑定到 onclick 按钮事件。当我将初始视图模型放在 document.ready 中时,我只能将它传递给其他函数。我从每个函数中获得的数据都是 100% 正确的。但是,每当我绑定视图模型时,它都会覆盖以前的绑定并且值不成立。下面是代码:
javascript
<
script type="text/javascript" language='javascript'>
var MyProject = ;
var viewModel;
MyProject.viewModel = "";
var invoiceModel;
$(document).ready(function InitializeInvoice()
$.ajax(
type: "Post",
url: "Default.aspx/InitializeModel",
data: ,
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
success: initializesinvoice
);
function initializesinvoice(msg)
var defaultdata = msg.d.Data;
invoiceModel = defaultdata;
MyProject.viewModel = ko.mapping.fromJS(invoiceModel);
ko.applyBindings(MyProject.viewModel)
;
)
function GetVendorInvoiceDefaults()
MyProject.viewModel = JSON.stringify(invoiceModel);
var data = 'invoice:' + MyProject.viewModel + '';
$.ajax(
type: "Post",
url: "Default.aspx/GetVendorInvoiceDefaults",
data: data,
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
success: GetVendorInvoiceDefaultsSuccess
);
function GetVendorInvoiceDefaultsSuccess(msg)
var defaultdata = msg.d.Data;
invoiceModel = defaultdata;
MyProject.viewModel = ko.mapping.fromJS(invoiceModel);
ko.applyBindings(MyProject.viewModel)
;
function GetVendorCode()
var vendormodel = JSON.stringify(invoiceModel);
var data = 'invoice:' + vendormodel + '';
$.ajax(
type: "Post",
url: "Default.aspx/GetVendorCode",
data: 'invoice:' + vendormodel + '',
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
success: GetVendorCodeSucess
);
function GetVendorCodeSucess(msg)
var defaultdata = msg.d.Data;
MyProject.viewModel = ko.mapping.fromJS(defaultdata);
ko.applyBindings(MyProject.viewModel)
;
#html#
<p> Invoice Description <asp:TextBox ID="txtdesc" runat="server" data-bind="value:InvoiceDescription"> </asp:TextBox></p>
<p> Distribution Code <asp:TextBox ID="txtdistcode" runat="server" data-bind="value:DistributionCode"></asp:TextBox></p>
<p> Vendor Code <asp:TextBox ID="txtvendor" runat="server" data-bind="value:VendorCode" ></asp:TextBox></p>
<p> <button onclick="InitializeInvoice()">InitializeInvoice</button></p>
<p><button id="btndefaults" onclick="GetVendorInvoiceDefaults()">GetVendorInvoiceDefaults</button></p>
<p><button id="btnvendor" onclick="GetVendorCode()">GetVendorCode</button><p>
</pre>
#ASPX file#
namespace WebApplication9
public partial class _Default : System.Web.UI.Page
protected void Page_Load(object sender, EventArgs e)
protected override void OnLoad(EventArgs e)
if (IsPostBack)
clientSideIsPostBack.Value = "Y";
else
clientSideIsPostBack.Value = "N";
base.OnLoad(e);
[WebMethod]
public static JsonResult InitializeModel()
var Invoice = new Invoice() InvoiceNumber = "1235", InvoiceDescription = "Hello World", DistributionCode = "" ;
JsonResult r = new JsonResult();
r.Data = Invoice;
return r; //serializer.Deserialize(Invoice, typeof(Invoice)) as JsonResult;
[WebMethod]
public static JsonResult GetVendorInvoiceDefaults(Invoice invoice)
JavaScriptSerializer serializer = new JavaScriptSerializer();
invoice.DistributionCode = "HELLO WORLD";
JsonResult r = new JsonResult();
r.Data = invoice;
return r;
//return new JsonResult() Data = invoice ;
[WebMethod]
public static JsonResult GetVendorCode(Invoice invoice)
JavaScriptSerializer serializer = new JavaScriptSerializer();
invoice.VendorCode = "AHM";
JsonResult r = new JsonResult();
r.Data = invoice;
return r;
public class Invoice
private string distributionCode;
private string vendorcode;
public string InvoiceNumber get; set;
public string InvoiceDescription get; set;
public string DistributionCode
get
return distributionCode ?? string.Empty;
set
distributionCode = value;
public string VendorCode
get
return vendorcode ?? string.Empty;
set
vendorcode = value;
【问题讨论】:
【参考方案1】:因此,您永远不应在多个地方或不止一次(每个 div)拨打此电话ko.applyBindings(MyProject.viewModel).
一旦应用了视图模型的绑定,它们就会被应用。 您永远不要重复此步骤! 这非常重要。当MyProject.viewModel
中的值更新时,绑定会自动更新 HTML。这就是重点。当你不止一次调用applyBindings
时,你会产生各种意想不到的行为。
设置您的视图模型,应用一次绑定,然后让所有其他代码正确更新视图模型。我建议在 document.ready
处理程序中执行此操作在执行其他任何操作之前,例如连接 ajaxy 的东西。
其次,当使用 KO Mapping 插件 per the documentation 时,您会像这样更新整个视图模型:ko.mapping.fromJS(data, viewModel);
每次调用 MyProject.viewModel = ko.mapping.fromJS(invoiceModel);
都会覆盖您的视图模型。
这是 Knockout 的另一个关键方面。因为可观察对象是函数,所以您可以通过将新值作为参数传递来更新它们,而不是像普通变量那样覆盖它们。
对:
viewModel.observable(newValue)
错误:
viewModel.observable = newvalue
【讨论】:
感谢您的 cmets。解决我的问题的方法是在页面加载时创建类的全局对象,这样类成员就可以随时使用这些方法。但我同意你提出的观点,都是有道理的。谢谢! +1 让我第六次阅读文档并最终获得它。顺便说一句,当前版本需要一个必须提供的映射参数:ko.mapping.fromJS(data, , viewModel);以上是关于将 knockoutjs 视图模型传递给多个 ajax 调用的主要内容,如果未能解决你的问题,请参考以下文章