Knockout json映射错误

时间:2015-05-06 17:20:59

标签: json knockout.js

我已经阅读了一些关于这个问题的帖子,但是想问一下,因为我自己的代码略有不同。我正在开发一个高尔夫游戏跟踪网站,并遇到了一个问题

我有以下观点:

@{
    ViewBag.Title = "Games";
}

<h2>Games</h2>
<table class="table-bordered">
    <thead>
        <tr>
            <th>Course</th>
            <th>Date</th>
            <th>Player</th>
            <th>Hole 1</th>
            <th>Hole 2</th>
            <th>Hole 3</th>
            <th>Hole 4</th>
            <th>Hole 5</th>
            <th>Hole 6</th>
            <th>Hole 7</th>
            <th>Hole 8</th>
            <th>Hole 9</th>
        </tr>
    </thead>
    <tbody data-bind="foreach: GameList">
        <tr>
            <td data-bind="text: CourseName"></td>
            <td data-bind="text: Date"></td>
        </tr>
        <!-- ko foreach: GameEntry -->
        <tr>
            <td></td>
            <td></td>
            <td data-bind="text:PlayerName"></td>
            <td data-bind="text:HoleOneScore"></td>
            <td data-bind="text:HoleTwoScore"></td>
            <td data-bind="text:HoleThreeScore"></td>
            <td data-bind="text:HoleFourScore"></td>
            <td data-bind="text:HoleFiveScore"></td>
            <td data-bind="text:HoleSixScore"></td>
            <td data-bind="text:HoleSevenScore"></td>
            <td data-bind="text:HoleEightScore"></td>
            <td data-bind="text:HoleNineScore"></td>
        </tr>
        <!-- /ko -->
    </tbody>
</table>
<script>
    function Game(data){
        var self = this;
        self.CourseName = ko.observable(data.CourseName);
        self.Date = ko.observable(data.Date);
        self.GameEntries = ko.observableArray(new GameEntry(data.GameEntries));
    }

    function GameEntry(data){
        var self = this;
        self.PlayerName = ko.observable(data.PlayerName);
        self.HoleOneScore = ko.observable(data.HoleOneScore);
        self.HoleTwoScore = ko.observable(data.HoleTwoScore);
        self.HoleThreeScore = ko.observable(data.HoleThreeScore);
        self.HoleFourScore = ko.observable(data.HoleFourScore);
        self.HoleFiveScore = ko.observable(data.HoleFiveScore);
        self.HoleSixScore = ko.observable(data.HoleSixScore);
        self.HoleSevenScore = ko.observable(data.HoleSevenScore);
        self.HoleEightScore = ko.observable(data.HoleEightScore);
        self.HoleNineScore = ko.observable(data.HoleNineScore);
    }

    function ViewModel() {
        var self = this;
        self.GameList = ko.observableArray([]);

        $.getJSON("/Games/GetGames", function (allData) {
            var mappedTasks = $.map(allData, function (item) { return new Game(item) });
            self.GameList(mappedTasks);
        });
    }

    $(document).ready(function () {       
        ko.applyBindings(new ViewModel());
    });
</script>

调用此控制器功能:

[HttpGet]
        public JsonResult GetGames()
        {
            return Json(JsonConvert.SerializeObject(GameManager.GetGames(), Formatting.Indented), JsonRequestBehavior.AllowGet);
        }

其中包含以下模型和映射:

public static List<GameModel> GetGames()
        {
            var gameList = new List<GameModel>();
            using (var context = new Entities())
            {
                var games = context.Games.ToList();
                foreach (var game in games)
                {
                    var model = new GameModel();
                    model.MapGame(game);
                    gameList.Add(model);
                }                
            }
            return gameList;
        }

public class GameModel
    {
        public string CourseName { get; set; }
        public DateTime Date { get; set; }

        public List<PlayerGameEntry> GameEntries { get; set; }

        public GameModel()
        {
            GameEntries = new List<PlayerGameEntry>();
        }

        public class PlayerGameEntry
        {
            public string PlayerName { get; set; }
            public int? HoleOneScore { get; set; }
            public int? HoleTwoScore { get; set; }
            public int? HoleThreeScore { get; set; }
            public int? HoleFourScore { get; set; }
            public int? HoleFiveScore { get; set; }
            public int? HoleSixScore { get; set; }
            public int? HoleSevenScore { get; set; }
            public int? HoleEightScore { get; set; }
            public int? HoleNineScore { get; set; }
        }

        public void MapGame(Game game)
        {

            CourseName = game.Course.CourseName;
            Date = game.Date;           

            foreach (var entry in game.GameEntries)
            {
               GameEntries.Add(new PlayerGameEntry
                {
                    PlayerName = entry.Golfer.PlayerName,
                    HoleOneScore = entry.HoleOneScore,
                    HoleTwoScore = entry.HoleTwoScore,
                    HoleThreeScore = entry.HoleThreeScore,
                    HoleFourScore = entry.HoleFourScore,
                    HoleFiveScore = entry.HoleFiveScore,
                    HoleSixScore = entry.HoleSixScore,
                    HoleSevenScore = entry.HoleSevenScore,
                    HoleEightScore = entry.HoleEightScore,
                    HoleNineScore = entry.HoleNineScore
                });
            }
        }
    }

我在浏览器中收到此错误:

Uncaught TypeError: Cannot use 'in' operator to search for '967' in [
  {
    "CourseName": "Green Hills",
    "Date": "2013-04-02T16:33:21.943",
    "GameEntries": [
      {
        "PlayerName": "Chris Camp",
        "HoleOneScore": 4,
        "HoleTwoScore": 5,
        "HoleThreeScore": 6,
        "HoleFourScore": 3,
        "HoleFiveScore": 4,
        "HoleSixScore": 4,
        "HoleSevenScore": 4,
        "HoleEightScore": 5,
        "HoleNineScore": 3
      }
    ]
  },
  {
    "CourseName": "Green Hills",
    "Date": "2015-05-01T13:08:41.783",
    "GameEntries": []
  },
  {
    "CourseName": "Green Hills",
    "Date": "2015-05-01T13:13:45.34",
    "GameEntries": [
      {
        "PlayerName": "Chris Camp",
        "HoleOneScore": 4,
        "HoleTwoScore": 3,
        "HoleThreeScore": 4,
        "HoleFourScore": 7,
        "HoleFiveScore": 5,
        "HoleSixScore": 2,
        "HoleSevenScore": 1,
        "HoleEightScore": 4,
        "HoleNineScore": 6
      }
    ]
  }
]

我认为getJson中的绑定会处理我根据我的observable设置的所有字段的映射,有什么我完全不理解knockout如何绑定这些数据?我这样做只是一个映射对象的过去,但没有一个子对象。

1 个答案:

答案 0 :(得分:1)

您的问题是您首先使用JsonConvert将某些数组序列化为JSON,然后将字符串传递给MVC Json方法,该方法将尝试再次将此字符串序列化为JSON。在这种情况下,getJSON回调中的数据变量将是string类型,它将包含你的json(它将是长度为967个字符的字符串,这就是你看到这个异常的原因)。

您需要使用以下代码替换控制器中的代码:

[HttpGet]
public JsonResult GetGames()
{
  return Json(GameManager.GetGames(), JsonRequestBehavior.AllowGet);
}