来自对象填充的可观察数组的信息不会显示在我的视图中

Information from my object filled observable array won't show up in my view

我发现了关于我在 SO 上遇到的问题的类似问题,但是 none 解决了我的问题。

加载页面时,我使用 AJAX 从数据库中检索对象数组。它们具有属性 IDnamescore.

数组将被放入一个名为 hs 的变量中。
当我 console.log 变量 hs 时,它会记录包含对象的数组,所以这不是问题所在。 (对吗?)

现在,当我加载页面时,它不显示来自这些对象的信息。这就是我遇到的问题!

这是我的视图模型的一部分:

 function initCanvas() {
    this.playerName = ko.observable("");
    this.chosenLevel = ko.observable();
    this.chosenDifficulty = ko.observable();

    this.availableLevels = ko.observableArray(['Mountains', 'Stars', 'Jungle']);
    this.difficulty = ko.observableArray(['Makkelijk', 'Normaal', 'Moeilijk']);
    this.highscores = ko.observableArray(hs);
    this.personalHighScore = ko.observable(localStorage.getItem("+score") || "Geen record!");

我的 HTML 看起来像这样:

        <table>             
            <tbody data-bind="foreach: highscores">
                <tr>
                    <td><span data-bind="text: name"></span></td>
                    <td><span data-bind="text: score"></span></td>
                </tr>
            </tbody>
        </table>

你们能帮帮我吗?我是 Knockout 的新手,所以如果这是一个愚蠢的问题,请原谅我。

编辑

这里有更多信息:

 hs = [];
    getHighScores();

function getHighScores() {
        var highScoreArray = [];
        $.ajax({
            url: "../php/score_server.php",
            data: {
                "action": "getScore"
            },

            type: 'GET',
            success: function (result) {
                var resultParsed = JSON.parse(result);
                $.each(resultParsed, function (key, value) {
                    hs.push(value);
                });
            },
            error: function (jqXHR, textStatus, errorThrown) {
                console.log(jqXHR);
                console.log(textStatus);
                console.log(errorThrown);
            },
            async: true
        });
    }

结果如下所示:

还有其他一些我无法修复的错误,比如 getHighScores() 被触发了两次,虽然我只调用了一次......而且分数是多少并不重要,PHP 我用 sendHighScore() 函数调用的文档将始终将 9 放入数据库中。但我稍后可能会为此提出另一个问题。

编辑 2

$(document).ready(function () {
    var ctx = document.getElementById('canvas').getContext('2d'),
        cW = ctx.canvas.width,
        cH = ctx.canvas.height,
        animateInterval,
        P,
        hs = [],
        paused = false;
    getHighScores();
    ko.applyBindings(new initCanvas());

    function getHighScores() {
        var highScoreArray = [];
        $.ajax({
            url: "../php/score_server.php",
            data: {
                "action": "getScore"
            },

            type: 'GET',
            success: function (result) {
                var resultParsed = JSON.parse(result);
                $.each(resultParsed, function (key, value) {
                    hs.push(value);
                });
            },
            error: function (jqXHR, textStatus, errorThrown) {
                console.log(jqXHR);
                console.log(textStatus);
                console.log(errorThrown);
            },
            async: true
        });
    }
    function initCanvas() {
        this.playerName = ko.observable("");
        this.chosenLevel = ko.observable();
        this.chosenDifficulty = ko.observable();

        this.availableLevels = ko.observableArray(['Mountains', 'Stars', 'Jungle']);
        this.difficulty = ko.observableArray(['Makkelijk', 'Normaal', 'Moeilijk']);
        this.highscores = ko.observableArray(hs);
        this.personalHighScore = ko.observable(localStorage.getItem("+score") || "Geen record!");

解决方案

我的固定 HTML:

<table>                     
    <tbody data-bind="foreach: highscores">
        <tr>
            <td><span data-bind="text: name"></span></td>
            <td><span data-bind="text: score"></span></td>
        </tr>
    </tbody>
</table>

我的固定 Javascript:

 function getHighScores() {
        var highScoreArray = [];
        $.ajax({
            url: "../php/score_server.php",
            data: {
                "action": "getScore"
            },

            type: 'GET',
            success: function (result) {

                var resultParsed = JSON.parse(result);
                $.each(resultParsed, function (key, value) {
                    hs.push(value);
                });
                ko.applyBindings(new initCanvas());
                $('#controls').find('input, select, button').prop('disabled', false);

            },

            error: function (jqXHR, textStatus, errorThrown) {
                console.log(jqXHR);
                console.log(textStatus);
                console.log(errorThrown);
            },
            async: true
        });
    }

当您创建视图模型 (initCanvas) 时,数组 hs 为空,因为它尚未等待 ajax 调用完成。在您成功回调 $.ajax 时,您应该 ko.applybindings。这样你实际上在 hs 中有数据用于敲除绑定:

            success: function (result) {
                var resultParsed = JSON.parse(result);
                $.each(resultParsed, function (key, value) {
                    hs.push(value);
                });
                ko.applyBindings(new initCanvas());

            }

更好的解决方案是设置可观察数组值。目前,您等待 post 到 return 有点违背了使用淘汰赛的目的。它看起来像这样。

替换:

ko.applyBindings(new initCanvas());

在您的原始示例中:

var canvasViewModel = new initCanvas();
ko.applyBindings(canvasViewModel);

然后在您的成功回调中,您需要像这样设置可观察值的值:

canvasViewModel.highscores(resultParsed);

而不是

$.each(resultParsed, function (key, value) {
   hs.push(value);
});
ko.applyBindings(new initCanvas());