【问题标题】:Knockout json mapping error淘汰赛json映射错误
【发布时间】:2015-07-16 23:45:55
【问题描述】:

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

我有以下观点:

@{
    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 中的绑定将处理映射我根据我的 observables 设置的所有字段,是否有什么我完全不了解敲除如何绑定这些数据?我已经这样做了,过去只有一个映射对象,但没有一个子对象。

【问题讨论】:

    标签: json knockout.js


    【解决方案1】:

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

    您需要将控制器中的代码替换为:

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

    【讨论】:

    • 谢谢这解决了我原来的问题。但是现在我收到以下错误:Uncaught TypeError: Cannot read property 'PlayerName' of undefined。必须完成这些可观察对象的映射。
    • 还注意到您将 GameEntries 数组放入 GameEntry 构造函数(应该接受单个 GameEntry)
    • 在这种情况下,每个游戏都可以有多个游戏条目,这就是我遇到的问题。您可以拥有最多 10 个条目的游戏
    猜你喜欢
    • 2014-03-20
    • 1970-01-01
    • 2012-06-08
    • 1970-01-01
    • 2012-09-05
    • 2012-12-05
    • 2015-03-30
    • 2017-07-07
    • 2014-03-26
    相关资源
    最近更新 更多