2016-02-01 100 views
0

我是Knockout的新手。我正在成功抽取數據,但是試圖根據記錄是否處於活動狀態來對其進行過濾。當我這樣做時,它發送正確的值,但我的可觀察數組是空的。Knockout JS ObservableArray丟失值

我用ajax填充它。我的理解是我填充了observable數組,除非要寫入數據庫或獲取新數據,否則不需要對服務器執行任何其他命中。所以一旦這個可觀察的數組有數據,我應該能夠過濾它而不用再次敲擊數據庫。這似乎不適用於我。我覺得我做錯了什麼。思考?

下面是代碼:

var sgsoip = window.sgsoip || {}; 
 
sgsoip.FunctionalAreaViewModel = function (ko, db) { 
 
    //'use strict'; 
 
    var self = this; 
 
    self.functionalAreas = ko.observableArray([]) 
 

 
    self.headers = [ 
 
     { title: '', sortPropertyName: '', asc: true }, 
 
     { title: 'Functional Area Name', sortPropertyName: 'FunctionalAreaName', asc: true }, 
 
     { title: 'Active', sortPropertyName: 'FunctionalAreaActive', asc: true } 
 
    ]; 
 
    self.filters = [ 
 
     { title: "Show All", filter: null }, 
 
     { title: "Active", filter: function (item) { return item.FunctionalAreaActive == 'true'; } }, 
 
     { title: "Inactive", filter: function (item) { return item.FunctionalAreaActive == 'false'; } } 
 
    ]; 
 

 
    self.activeFilter = ko.observable(self.filters[0].filter); 
 

 
    self.setActiveFilter = function (model, event) { 
 
     self.activeFilter(model.filter); 
 
    } 
 

 
    self.filteredItems = ko.computed(function() { 
 
     if (self.activeFilter()) { 
 
      return ko.utils.arrayFilter(self.functionalAreas, self.activeFilter()); //When hitting filter self.functionalAreas is empty 
 
     } else { 
 
      return self.functionalAreas(); //this works as expected 
 
     } 
 
    }); 
 

 
    self.activeSort = self.headers[1]; 
 
    function _init() { 
 
     db.getFunctionalAreas(function (data) { 
 
      //var a = []; 
 
      ko.utils.arrayForEach(data || [], function (item) { 
 
       self.functionalAreas.push(new sgsoip.FunctionalArea(item.FunctionalAreaID, item.FunctionalAreaName, item.FunctionalAreaActive)); 
 
      }); 
 
      //self.functionalAreas(a); 
 
     }); 
 
    } 
 
    
 
    _init(); 
 
    return { 
 
     functionalAreas: functionalAreas, 
 
     sortedFunctionalAreas: sortedFunctionalAreas, 
 
     removeFunctionalArea: removeFunctionalArea 
 
    }; 
 
}(ko, sgsoip.DataContext);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> 
 
<div class="btn-group" data-bind="foreach: filters"> 
 
     <button class="btn btn-small" data-bind="click: setActiveFilter, text: title"></button> 
 
    </div> 
 

 
    <table class="table" id="gridoutput"> 
 
     <thead> 
 
      <tr data-bind="foreach: headers"> 
 
       <th><a href="#" data-bind="click: filteredItems, text: title"></a></th> 
 
      </tr> 
 
     </thead> 
 
     <tbody data-bind="foreach: filteredItems"> 
 
      <tr> 
 
       <td><a href="javascript:void(0);" data-bind="click: removeFunctionalArea" title="Delete"><i class="icon icon-trash"></i></a></td> 
 
       <td data-bind="text: FunctionalAreaName"></td> 
 
       <td data-bind="text: FunctionalAreaActive"></td> 
 
      </tr> 
 
     </tbody> 
 
    </table>

編輯 - 添加一些缺失的東西對於那些問。

var sgsoip = window.sgsoip || {}; 
 
sgsoip.DataContext = (function ($) { 
 
    'use strict'; 
 
    var me = { 
 
     getFunctionalAreas: getFunctionalAreas, 
 
     removeFunctionalArea: removeFunctionalArea, 
 
     saveFunctionalArea: saveFunctionalArea 
 
    }; 
 
    function getFunctionalAreas(callback) { 
 
     var functionalareas = null; 
 
     if ($.isFunction(callback)) { 
 
      //functionalareas = localStorage["functionalareas"]; 
 
      //alert('test'); 
 

 
      //if (functionalareas != "undefined") { 
 
      // callback(functionalareas); 
 
      //} else { 
 
      $.getJSON('/FunctionalAreas/GetJsonData', function (data) { 
 
        //localStorage["functionalareas"] = JSON.stringify(data.FunctionalAreas); 
 
       callback(data); 
 
       }); 
 
      //} 
 
     } 
 
    } 
 

 
    function removeFunctionalArea(functionalArea) { 
 

 
    } 
 

 
    function saveFunctionalArea(functionalArea) { 
 

 
    } 
 
    return me; 
 
})(jQuery); 
 

 

 
var sgsoip = window.sgsoip || {}; 
 
sgsoip.FunctionalArea = function (FunctionalAreaID, FunctionalAreaName, FunctionalAreaActive) { 
 
    'use strict'; 
 
    this.FunctionalAreaID = ko.observable(FunctionalAreaID); 
 
    this.FunctionalAreaName = ko.observable(FunctionalAreaName).extend({ required: "Functional Area Name is required" }); 
 
    this.FunctionalAreaActive = ko.observable(FunctionalAreaActive).extend({ required: "Active is required" }); 
 
    this.HasError = ko.pureComputed(function() { 
 
     return this.FunctionalAreaActive.hasError() || this.FunctionalAreaName.hasError(); 
 
    }, this); 
 
};

編輯 貌似我可以添加更多的澄清。它不會丟失數據。我通過Knockout代碼完成所有步驟。它確實通過觀測值循環來比較。

我到下面的代碼段:

arrayFilter: function (array, predicate) { 
 
      array = array || []; 
 
      var result = []; 
 
      for (var i = 0, j = array.length; i < j; i++) 
 
       if (predicate(array[i], i)) 
 
        result.push(array[i]); 
 
      return result; 
 
     },

而且它從不執行result.push(陣列[I])線。

+0

您的示例沒有定義'db'或'FunctionalArea';我試圖在小提琴中進行測試。你能提供一個獨立的工作示例嗎? – dfperry

+0

在一定程度上我可以。但是我想你必須用靜態json替換我的json調用。 1秒。我會更新帖子。 –

+0

它甚至不需要是ajax調用,只需包含數據並在調試添加的最後一位代碼時在_init方法 – dfperry

回答

1

當迭代或以其他任何方式與您觀察到的陣列的工作,你需要記住,在末尾加上括號,就像這樣:

return ko.utils.arrayFilter(self.functionalAreas(), self.activeFilter()); 

使用是在實際執行的方法時,這是唯一observableArray(如push,remove等),你可以省略括號。

+0

我也這麼認爲,即使我遵循的例子沒有它:http://ryanrahlf.com/filtering-table-data-with-knockout-js/我做了改變,仍然得到相同的結果。就好像在初始頁面加載後的任何操作清除了Observablearray。 –

+0

過了幾天。這最終是正確的,但與評論有點不同。它導致了正確的答案。儘管很多例子顯示這個工作沒有()在線,但它並沒有爲我工作。我正在使用knockout-3.4.0。問題出在我的self.filters數組中,我沒有在這行上使用() - return item.FunctionalAreaActive()=== true;並導致它失敗。 –

+0

事實上,昨天我看了John Papa關於YouTube上淘汰賽的演示文稿,他特別指出,淘汰賽非常聰明,足以讓人瞭解何時財產沒有()結尾,只要它是尾隨屬性。他說過這件事。不管什麼東西都是一樣的。無論什麼(),而是像事物一樣。無論什麼東西都是無效的,而是事物。無論如何。如果這是有道理的。所以要麼是淘汰賽比他發表演講時更嚴格,要麼是在這裏發生的其他事情。 –