【问题标题】:Mapping a JSON array with knockout.js mapping plugin & and view rendering not working使用 knockout.js 映射插件 & 映射 JSON 数组和视图渲染不起作用
【发布时间】:2011-12-01 16:15:42
【问题描述】:

我在将 .NET JavaScriptSerializer 生成的 JSON 数组映射到 knockout.js 时遇到问题。数组是这样生成的(为了方便而缩短):

OrderProposalFacade[] proposals = new OrderProposalFacade[order.OrderProposals.Count];

foreach (OrderProposal proposal in order.OrderProposals)
{
    proposals[i++] = new OrderProposalFacade(proposal);
}

ViewBag.OrderProposals = new JavaScriptSerializer().Serialize(proposals);

生成的 JSON 字符串是这样的:

[{ "ProposalId":1,"ProgrammedWeek":null,
   "ProposalValue":120,"ProposalValueCorrected":130,
   "ProposalDateSent":"01-12-2011","ProposalDateCorrected":"01-12-2011",
   "ServiceId":1,"ServiceDescriptiveId":"OS001","ProposalState":2
 },
 {//another similar object}
]

在 ASP.NET MVC 视图中,我这样做是为了绑定数组:

var initialData = ko.mapping.fromJSON(<%: new HtmlString(ViewBag.OrderProposals as string) %>);
var viewModel = {
    proposals: ko.observableArray(initialData),
    //some methods; removed to ease reading
};
ko.applyBindings(viewModel);

问题: proposals 数组应该由 knockout.js 模板呈现,但没有呈现任何内容。使用 Firebug,我在 initialData 数组上看不到任何对象,所以我认为在初始化它时有错误,因此,proposals。与模板的绑定是这样的:

<div id="service-orders" data-bind='template: { name: "proposal-template", foreach: proposals }' style="margin:0 -.7em 0 -0.5em;"></div>

如果我删除 ko.mapping.fromJSON() 一切正常,即,模板将使用 proposals 数组上的值呈现。 但是当我更新initialData 数组上的对象的值时,会出现另一个问题。据我了解,如果我更新一个可观察的属性,模板会再次呈现(因此是 knockout.js 映射),但如果不映射所有属性,它就不会发生,对吧?

简而言之,我需要映射initialData 数组上的所有属性,以便在我更改其中一个对象的值时使它们可观察以更新我的视图,但它不是不工作。

有什么想法吗?提前谢谢!

【问题讨论】:

  • 首先,您为什么使用HtmlString?简单的&lt;%:ViewBag.OrderProposals %&gt; 就足够了。其次,更改observableArray 中任何项目的值不会再次呈现模板。 observableArray 仅观察数组中的添加/删除,而不观察其单个项的修改。
  • @nEEbz:好吧,我的假设是错误的。如何检测变化?我应该使用 updateFromJS 吗?
  • ko.mapping.fromJSON(&lt;%: PROPOSAL STUFF %&gt;); 不是完全由 ASP 内联静态渲染/生成的吗?换句话说,在“编译”时不需要 ko.mapping.fromJSON,即只有在运行时动态填充 intialdata 时才需要它。
  • 您可能也不应该在其中使用 : ,但请坚持使用 = 因为您不希望它被转义,序列化程序已经为您完成了。

标签: asp.net-mvc-3 knockout.js


【解决方案1】:

终于解决了!最终的 Javascript 是这样的:

var initialData = <%: new HtmlString(ViewBag.OrderProposals as string) %>;
var viewModel = {
    proposals: ko.observableArray(),
    //some methods; removed to ease reading
};

viewModel.proposals = ko.mapping.fromJS(initialData);

ko.applyBindings(viewModel);

我所做的 2 处更改:

  • 我打电话给ko.mapping.fromJS(initialData),而不是ko.mapping.fromJSON(initialData)。不舒尔,但我似乎 .fromJSON() 在映射我提出的问题的数组时遇到了一些问题;
  • .fromJS() 方法在 viewModel 创建后调用。

【讨论】:

  • 我认为 fromJSON 不起作用,因为当您从 HtmlString 创建 javascript 字符串时,您会收到一个没有编码的字符串,这被认为是有效的 Javascript 对象但不是有效的 JSON。要拥有一个有效的 JSON 对象,您将不需要使用 HtmlString,但在这种情况下,您将遇到一些需要解析的无效字符的问题。我认为使用 fromJSON 的唯一原因是当您进行从服务器返回有效 JSON 流的 ajax 调用时。另一种方法是将您的 initialData 转换为 JSON。
猜你喜欢
  • 2015-04-18
  • 2012-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-04
相关资源
最近更新 更多