2013-11-22 29 views
0

我嘗試使用Knockout JS顯示錶中的項目列表。這就像一個典型的搜索界面,用戶鍵入查詢,界面顯示搜索引擎返回的結果列表。我首先通過AJAX調用從服務器檢索它們,然後嘗試綁定它們。這適用於第一個查詢。但是,當我嘗試第二個查詢(和後續查詢)時,每個結果項目被表示10次(重複),然後對於第三個查詢,每個項目顯示爲30次(依此類推)。以下是代碼。使用Knockout JS進行Ajax查詢

<body > 
<p> 
    <input type="search" id="skynet-query" name="q" placeholder="scientific search" autofocus /> 
    <input type="submit" id="skynet-submit" value="Ignite!" onclick="getAttachments(document.getElementById('skynet-query').value)" /> 
</p> 
<article data-bind="foreach: seats"> 
     <h3> 
      <input data-bind="attr:{value: papers().id }" type="checkbox" name="article-to-basket" /> 
      <a data-bind="attr:{href: papers().url }, text: papers().title"> </a> 
     </h3> 
     <address class="authors" data-bind="text: papers().authors"/> 
</article> 
</body> 

以下是腳本的一部分

<script> 

var array = new Array(); 

function getAttachments(keyword) { 

    var request = $.ajax({ 
    type: "GET", 
    datatype: "json", 
    url: "get-papers?q="+keyword+"&format=json&full-articles=true&kw-count=10&article-count=10&task-type=m1" 
    }); 

    request.done(function (response) { 

    for (i=0;i<response.articles.length; i++){ 
     array[i] = new PaperData(response.articles[i]); 
    } 
    ko.cleanNode(document); 
    ko.applyBindings(new ReservationsViewModel()); 
    console.log("DONE"); 
    }); 

} 

function PaperData(papers) { 
    var self = this; 
    self.papers = ko.observable(papers); 
} 

function ReservationsViewModel() { 
    //var self = this; 
    self.seats = ko.observableArray(array); 

} 

</script> 

有人可以幫我找到什麼不對的代碼?

這就是我的數據模型看起來像

{ 
    articles: [ 
    { 
    "is-saved": false, 
    title: "title", 
    abstract: "Abstract", 
    date: "2005-01-01 00:00:00", 
    "publication-forum": "forum", 
    "publication-forum-type": "article", 
    authors: "Authors", 
    keywords: "keyword1, keyword2, keywordn", 
    id: "4f5a318e573ce53e03000015" 
    } 
    ] 

    } 
+0

其實在第三次顯示每個項目45次:(非常奇怪,我不明白爲什麼 – Paba

+0

你的'陣列'是「全局」,你總是添加項目,你永遠不會清除它.. – nemesv

+0

'座位'從哪裏來?你的觀點模型似乎不完整。 – Tomalak

回答

1

你的方法敲除是不完全正確。

  • 您在屏幕上顯示的每個值都應該是一個與您的視圖模型相關的可觀察值。
  • 例如,輸入具有名稱的元素是不必要的 - value綁定負責更新視圖模型。你永遠不需要通過名字來尋址<input>
  • 不要有史以來使用內聯事件處理程序,如onclick。不在淘汰賽中,也不在其他地方。
  • 請勿使用全局變量。你的問題來自於使用全局變量array,實際上它應該是你的視圖模型中可觀察的數組。
  • 不要將所有事情都清理出來,只是因爲改變了某些東西而重新構建了整個視圖模型。淘汰賽將處理任何部分更新。

這是一個改進的方法。

<p> 
    <input type="search" data-bind="value: query" placeholder="scientific search" autofocus /> 
    <input type="submit" data-bind="click: getAttachments" /> 
</p> 
<article data-bind="foreach: seats"> 
    <h3> 
     <input data-bind="value: id, checked: selected" type="checkbox" /> 
     <a data-bind="attr: {href: url}, text: title"></a> 
    </h3> 
    <address class="authors" data-bind="text: authors"/> 
</article> 

function PaperData(data) { 
    ko.utils.extend(this, data); 
    this.selected = ko.observable(false); 
} 
PaperData.create = function (data) { 
    return new PaperData(data); 
}; 

function ReservationsViewModel() { 
    var self = this; 

    self.query = ko.observable(); 
    self.seats = ko.observableArray(); 

    self.queryParams = { 
     "q": self.query, 
     "format": "json", 
     "full-articles": true, 
     "kw-count": 10, 
     "article-count": 10, 
     "task-type": "m1" 
    }; 

    self.getAttachments = function() { 
     $.get("get-papers", ko.toJS(self.queryParams)) 
     .then(function (response) { 
      return ko.utils.arrayMap(response.articles, PaperData.create); 
     }) 
     .done(self.seats); 
    }; 
} 

ko.applyBindings(new ReservationsViewModel()); 

  • 您可以使用.then()改造上飛Ajax響應數據。
  • 您可以使用.done()將轉換後的結果寫入可觀察值。
  • 使queryParams成爲視圖模型的獨立屬性允許您動態調整其他查詢參數,如"q"所示。
  • 您可以使用ko.utils.extend將屬性從一個對象轉移到另一個對象。或者,您可以使用映射插件。
+0

感謝您的非常好的答案。我意識到我還沒有理解Knockout權利的概念。我嘗試用你的代碼替換我的代碼,但得到了以下錯誤。未引用的ReferenceError:無法處理綁定「value:function(){return id}」 消息:id未定義 - 這可能是因爲值id不在數據,所以我用this.id替換它然後這個錯誤消失了,但我沒有結果 – Paba

+0

不要在你的綁定聲明中使用任何JavaScript代碼。像'「value:function(){return id}」''不應該發生。所有計算都應該在視圖模型中進行,綁定應該只包含屬性名稱。出於調試目的,嘗試將'

'添加到有問題的模板部分。通過這種方式,您可以檢查Knockout試圖在任何情況下使用的實際對象。 –
                        
                            
    Tomalak
                                
                            
                        
                    

+0

當然,我不得不對你的數據模型進行一些猜測,因爲你沒有顯示任何JSON。我敢肯定,如果您逐步瞭解代碼,您將能夠弄清楚特定情況下的情況。 – Tomalak