如何将地图模型淘汰出局

时间:2016-01-03 17:33:21

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

如何将数组从我的模型映射到knockout viewModel?

我试过这个:

@using Newtonsoft.Json
   @model Hotel.Web.Controllers.FoodOrderModelView

   <table class="table table-responsive table-hover" data-bind="foreach: Items">
     <tr class="row">
       <td>
        <label data-bind="text: $data"></label>
        <label data-bind="text: Name"></label>
       </td>
     </tr>                            
  </table>

    <script>        
        function viewModel() {
            self = this;
            self.Items = ko.observableArray([]);
            var jsonModel = @Html.Raw(JsonConvert.SerializeObject(Model.LunchItems, new JsonSerializerSettings() { ReferenceLoopHandling  = ReferenceLoopHandling.Ignore}));
            console.log(jsonModel);
            var mvcModel = ko.mapping.fromJS(jsonModel,{}, self);
            self.Items(mvcModel);
            console.log(self.Items);
        };

        $(function () { 
            var myViewModel = new viewModel();
            ko.applyBindings(myViewModel);   
        });
    </script>

我得到了正确的JSON和奇怪的信息。

在控制台上我得到这个日志:

为什么我看不到mvcModel?

1. [Object, Object, ...]
0:
Object Count: 0
Name: " item"
   ...
2. function observable() {
        if (arguments.length > 0) {
            // Write

            // Ignore writes if the value hasn't changed
            if (observable.isDifferent(observable[observableL…

编辑:

JSON:

[
    {
        "LunchOrderItemId": 0,
        "FoodItem": {
            "LunchItemID": 1,
            "Name": " item",
            "Price": 196,
            "Description": " item description",
            "Category": 2,
            "File": null,
            "FileId": 1
        },
        "FoodItemId": 0,
        "Count": 0
    },
    {
        "LunchOrderItemId": 0,
        "FoodItem": {
            "LunchItemID": 2,
            "Name": "1 item",
            "Price": 29,
            "Description": "1 item description",
            "Category": 2,
            "File": null,
            "FileId": null
        },
        "FoodItemId": 0,
        "Count": 0
    },
    {
        "LunchOrderItemId": 0,
        "FoodItem": {
            "LunchItemID": 3,
            "Name": "2 item",
            "Price": 19,
            "Description": "2 item description",
            "Category": 2,
            "File": null,
            "FileId": null
        },
        "FoodItemId": 0,
        "Count": 0
    }
]

这里有小提琴手:https://jsfiddle.net/ez358nv6/

2 个答案:

答案 0 :(得分:1)

尝试首先使用JSON.parse(jsonModel)将JSON解析为JS对象, 了解如何在代码片段中解析json到js对象:

var jsonModel = '[{"LunchOrderItemId":0,"FoodItem":{"LunchItemID":1,"Name":" item","Price":196.00,"Description":" item description","Category":2,"File":null,"FileId":1},"FoodItemId":0,"Count":0},{"LunchOrderItemId":0,"FoodItem":{"LunchItemID":2,"Name":"1 item","Price":29.00,"Description":"1 item description","Category":2,"File":null,"FileId":null},"FoodItemId":0,"Count":0},{"LunchOrderItemId":0,"FoodItem":{"LunchItemID":3,"Name":"2 item","Price":19.00,"Description":"2 item description","Category":2,"File":null,"FileId":null},"FoodItemId":0,"Count":0}]';

function viewModel() {
          self = this;
          self.Items = ko.mapping.fromJS([]);
          ko.mapping.fromJS(JSON.parse(jsonModel),self.Items);                  
          console.log(self.Items());
        };

        $(function() {
          var myViewModel = new viewModel();
          ko.applyBindings(myViewModel);
        });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>

<table class="table table-responsive table-hover" data-bind="foreach: Items">
  <tr class="row">
    <td>
      <label data-bind="text: $data.FoodItem.Name"></label>
      <label data-bind="text: $data.FoodItem.Description"></label>
    </td>
  </tr>
</table>

  

但这是一种解决方法,因为您使用JSON.Net来序列化模型并返回JSON字符串,您可以使用它来生成模型@Html.Raw(Json.Encode(Model)),它将是来自JSON的JS对象。

答案 1 :(得分:1)

您的代码中存在各种问题,最明显的是:

  • 保存 fromJS的结果以及提供self作为第三个参数(即更新目标)。从我看到的后者应该足够了。
  • 您未正确宣布selfvar
  • 您的JSON 一个数组,但如果您想使用fromJS将其作为目标应用于self,则JSON应该是一个{{1}的对象1}} property。
  • 您的视图假定所有Items都具有Items属性,但根据您自己的JSON,它嵌套了一层。

顺便说一句,你应该Name作为进入Items的东西的属性。你可以在c#端修复它,或者你可以在我的例子中解决它,如下所示。

通过修复这些问题,我们可以使用稍微改进的代码示例:

&#13;
&#13;
fromJS
&#13;
// Abbreviated
var rawJson = [
    {
      "LunchOrderItemId": 0,
      "FoodItem": {
        "LunchItemID": 1,
        "Name": " item"
      }
    },
    {
      "LunchOrderItemId": 0,
      "FoodItem": {
        "LunchItemID": 2,
        "Name": "1 item"
      }
    }
];

function viewModel() {
  var self = this;
  self.Items = ko.observableArray([]);
  var jsonModel = { Items: rawJson };
  ko.mapping.fromJS(jsonModel, {}, self);
};

var myViewModel = new viewModel();
ko.applyBindings(myViewModel);
&#13;
label { padding: 4px; border: 1px solid gray; display: inline-block; }
&#13;
&#13;
&#13;