【问题标题】:Knockout.js: Unable to parse bindings from JSONKnockout.js:无法解析来自 JSON 的绑定
【发布时间】:2012-10-31 06:40:00
【问题描述】:

我有一个通过 AJAX 获取 JSON 并创建新任务的视图模型,但 Knockout 不断给我一个绑定错误。

如果我直接在我的视图模型中对来自服务器的数据进行硬编码,我不会收到任何错误。

我的视图模型创建了一个新任务,它有一个 id、一个问题和一些替代品,它本身有一个文本和正确的布尔标志。

以下代码运行良好:

function Task(data) {
    var self = this;

    self.id = data.id;
    self.question = ko.observable(data.question);

    var alts = new Array();
    $(data.alternatives).each(function(index){
        alts.push(new Alternative(data.alternatives[index].alternative, data.alternatives[index].correct));
    });

    self.alternatives = ko.observableArray(alts);
}
function Alternative(alternativeText, correctAnswer) {
    var self         = this;
    self.alternative = ko.observable(alternativeText);
    self.correct     = ko.observable(correctAnswer);
}
function TaskViewModel() {
    var self = this;

    var data = {
        id: 5,
        question: 'test',
        alternatives: [{
            alternative: 'alt 1',
            correct: false
        },{
            alternative: 'alt 2',
            correct: true
        },{
            alternative: 'alt 3',
            correct: false
        }]
    };

    self.task = new Task(data);
}

但是,如果我将硬编码的data 变量与来自服务器的真实数据进行交换:

function TaskViewModel() {
    var self = this;

    $.getJSON('/data', function(data){
        self.task = new Task(data);
    });
}

淘汰赛给了我这个错误:

Error: Unable to parse bindings.
Message: ReferenceError: Can't find variable: task;
Bindings value: value: task.question

来自 URL 的数据如下所示:

{"id":5,"question":"test","alternatives":[{"alternative":"alt 1","correct":false},{"alternative":"alt 2","correct":true},{"alternative":"alt 3","correct":false}]}

我似乎无法弄清楚为什么这不起作用:/

【问题讨论】:

    标签: jquery ajax json knockout.js knockout-2.0


    【解决方案1】:

    在应用绑定时,您的视图模型实际上并没有 task 属性。你需要给它一些绑定的东西。

    有几种方法可以解决这个问题。

    可能最简单的方法是使task 可观察并将其设置为ajax 调用的结果。您可能需要调整绑定以适应这一变化。

    function TaskViewModel() {
        var self = this;
        self.task = ko.observable();
    
        $.getJSON('/data', function(data){
            self.task(new Task(data));
        });
    }
    

    更灵活的选择是为您的Task 对象添加单独的初始化方法并设置任务(未初始化)。然后作为ajax调用的结果,调用初始化方法对其进行初始化。当然,您必须调整任务对象的初始化代码。

    function TaskViewModel() {
        var self = this;
        self.task = new Task();
    
        $.getJSON('/data', function(data){
            self.task.init(data);
        });
    }
    
    function Task() {
        var self = this;
        self.id = ko.observable();
        self.question = ko.observable();
        self.alternatives = ko.observableArray();
    
        self.init = function (data) {
            self.id(data.id);
            self.question(data.question);
            self.alternatives(ko.utils.arrayForEach(data.alternatives, function (item) {
                return new Alternative(item.alternative, item.correct);
            }));
        };
    }
    

    【讨论】:

    • 谢谢伙计。我实际上是在您使用初始化方法(您在此处介绍的)提到的事情之后发现了这一点。这使它完美地工作:)
    【解决方案2】:

    这篇文章包含了在 source 为 null 时处理绑定的多种方法。

    KnockoutJS binding when source is null/undefined

    如果您对不可绑定的 UI 消失感到满意,我建议您使用 with

    如果selectedItem 为空,则该元素甚至不会显示。

    <div data-bind="with: selecteditem">
        <form>
            <fieldset>
                <div>
                    <label>first name</label>
                    <input data-bind="value: firstname"></input>
                </div>
                <div>
                    <label>lasst name</label>
                    <input data-bind="value: lastname"></input>
                </div>
            </fieldset>
            <div>
                <a href="#" data-bind="click: $root.savechanges">Save</a>
            </div>
        </form>
    </div>
    

    【讨论】:

    • 注意:使用这种方法,当selecteditem 为空时,此 div 将从 DOM 中删除,因此如果您附加了非“实时”事件处理程序,则它可能无法正常工作
    猜你喜欢
    • 1970-01-01
    • 2020-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-20
    • 2017-01-01
    • 1970-01-01
    相关资源
    最近更新 更多