2012-11-11 53 views
2

我有一個視圖模型,通過AJAX獲取JSON,並創建一個新的任務,但敲除不斷給我一個綁定錯誤。Knockout.js:無法解析JSON綁定

如果我直接在我的視圖模型中硬編碼來自服務器的數據,我不會收到任何錯誤。

我的視圖模型創建一個新的任務,它有一個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); 
} 

但如果我exhcange硬編碼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}]} 

我似乎無法找出爲什麼這是行不通的:/

回答

6

您的視圖模型不實際應用你綁定的時候有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); 
     })); 
    }; 
} 
+0

謝謝你。實際上,在你使用初始化方法提到的東西(你在這裏介紹過)之後,我想到了這一點。這使得它正常工作:) –

4

這篇文章包含了很多方法可以處理當源爲空時的綁定。

KnockoutJS binding when source is null/undefined

如果你的消失是與你的unbindable UI OK我建議使用with

如果selectedItem爲null,則該元素甚至不會顯示。

<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> 
+0

注意:使用這種方法,當'selecteditem'爲null時,這個div將從DOM中移除,因此如果您有非'活'事件處理程序附加到它,那麼它可能無法工作 –

+0

+1回答! – Legend