将JSON绑定到knockout模板不起作用

时间:2013-06-07 11:59:54

标签: json jquery knockout.js knockout-mapping-plugin

嗨,我有这个ajax电话:

$.ajax({
        type: "POST",
        url: "wsCart.asmx/GetShippingRates2",
        contentType: "application/json; charset=utf-8",
        cache: false,
        data: datastring,
        dataType: "json",
        success: function (d) {
            alert(JSON.stringify(d));
            vm.shippingOptions = ko.mapping.fromJS(d);
        }
});

这是JSON

{"d":"[
    {\"Name\":\"Fedex - Error\",\"InternalName\":\"11\",\"Picture\":null,\"Costs\":0.0,\"Delivery\":\"2013-06-21T13:48:43.8220537+02:00\",\"ExtraInfo\":null},
    {\"Name\":\"Normal shipment\",\"InternalName\":\"normal\",\"Picture\":\"/images/blank.gif\",\"Costs\":2.5,\"Delivery\":\"0001-01-01T00:00:00\",\"ExtraInfo\":null},
    {\"Name\":\"UPS - Expedited\",\"InternalName\":\"08\",\"Picture\":\"/images/ups-logo.png\",\"Costs\":122.0,\"Delivery\":\"2013-06-21T13:48:37.4170513+02:00\",\"ExtraInfo\":\"\"},
    {\"Name\":\"UPS - Saver\",\"InternalName\":\"65\",\"Picture\":\"/images/ups-logo.png\",\"Costs\":122.46,\"Delivery\":\"2013-06-08T00:00:00\",\"ExtraInfo\":\"\"}]"}

这是我的GetShippingRates2方法:

var shipOptions = new List<ShipmentRateOption>();
shipOptions.Add(staticShip);
List<ShipmentRateOption> a = shipOptions.OrderBy(p => p.Costs).ToList();
return JsonConvert.SerializeObject(a);

我的淘汰赛(viewmodel)有:

var shipOptions = [];
function ovm() {
    var self = this;
    self.shippingOptions = ko.observableArray(shipOptions);
}   
var vm = new ovm();
ko.applyBindings(vm);

ajax调用由click事件上的jquery触发。我必须将数组绑定到的HTML:

<table style="width: 60%;">
    <tr data-bind="template: { foreach: shippingOptions() }">
        <td><label><input name="shipmentoptions" type="radio" data-bind="value: Name" /><span data-bind="text: Name"></span></label></td>
        <td style="text-align: right;">&euro;</td>
        <td style="text-align: center;">pic</td>
    </tr>
</table>

我找到了几个关于这个主题的SO问题,但不知何故,大多数都是MVC。 This one接近了,但不知何故对我没有帮助。我将上面提到的JSON作为警报并且在调试时遇到问题,并且感觉json中的d:导致绑定问题。但我找不到解决方案。有人可以指出我正确的方向吗?

提前感谢!!

修改 已更改为ko.mapping.fromJS(d.d, {}, vm.shippingOptions);<table style="width: 60%;" data-bind="foreach: shippingOptions"> 但现在我明白了:

name not defined

1 个答案:

答案 0 :(得分:1)

您的首要问题是JSON中的d,因此您只需使用fromJS

致电d.d
vm.shippingOptions = ko.mapping.fromJS(d.d);

然而,这不会单独起作用,因为要设置一个observable的值,你需要将其称为函数,所以你需要写:

vm.shippingOptions(ko.mapping.fromJS(d.d));

但是因为fromJS将返回一个可观察数组,你最终会得到一个shippingOptions可观察数组,其中包含另一个可观察数组...这可能不是你想要的。

因此,对于最终且正确的解决方案,您需要使用fromJS的不同重载,该重载采用现有数组并填充新数据:

ko.mapping.fromJS(d.d, {}, vm.shippingOptions);

在这种情况下,您需要从foreach绑定中删除()

<tr data-bind="template: { foreach: shippingOptions }">

演示JSFiddle