2012-12-12 132 views
6

我有一個網格和頁面上的選擇控件。選擇任何選擇值都會觸發網格更新。該更新是使用計算完成的。我可以手動觸發網格更新,例如,在將新值添加到網格的情況下?Knockout.js:手動觸發計算

function vm(){ 
    var self = this; 

    self.items = ko.observableArray([]); 
    self.chosen_category = ko.observable(""); 

    self.pager = { 
     page_namber : ko.observable(1), 
     page_size : ko.observable(10) 
    }; 

    self.sort = { 
     field : ko.observable('name'), 
     dist : ko.observable('asc') 
    }; 
    // etc. 

    self.fetch = ko.computed(function(){ 
     $.ajax({ 
       url: '/api/items/', 
       type: 'GET', 
       data: ko.toJSON(self), 
       contentType: 'application/json', 
       success: self.items 
      }); 
    }, self); 


     self.add_item = function() { 
     //here I want to update the grid 
     self.fetch(); // not work 
     }; 
} 

當然,我可以把它移到一個單獨的功能,但我正在尋找一個清晰的解決方案。 謝謝!

工作版本:

  function vm() { 
      var self = this; 

      self.items = ko.observableArray([]); 
      self.chosen_category = ko.observable("test"); 

      self.pager = { 
       page: ko.observable(1), 
       size: ko.observable(10) 
      }; 

      self.sort = { 
       field: ko.observable('name'), 
       dist: ko.observable('asc') 
      }; 

      self.fetch = function() { 
       var data = { 
        category: self.chosen_category(), 
        pager: ko.toJS(self.pager), 
        sort: ko.toJS(self.sort) 
       }; 

       $.ajax({ 
        url: '/api/items/', 
        type: 'POST', 
        data: ko.toJSON(data), 
        contentType: 'application/json', 
        success: self.items 
       }); 
      }; 

      self._auto_update = ko.computed(self.fetch).extend({ throttle: 1 }); ; 

      self.add_item = function() { 
       self.fetch(); 
      }; 
     } 
+1

你不需要手動更新它,因爲項目是一個observableArray。但我不確定我喜歡你使用計算的觀測值的方式 – Anders

+0

我認爲KnockOut的想法是你讓事情可觀察,而不是自己觸發它。 fetch方法應該通過更改集合自動調用。我在研究如何,你有更完整的例子嗎? – EricG

回答

9

這是更好地與subscription而不是computed做到這一點。在這種情況下,你可以定義取功能使用兩種訂閱和人工呼叫:

function vm(){ 
    var self = this; 

    self.items = ko.observableArray([]); 
    self.chosen_category = ko.observable(""); 

    self.fetch = function(){ 
    $.get('/api/items/' + self.chosen_category(), self.items); 
    }; 

    self.chosen_category.subscribe(self.fetch); 


    self.add_item = function() { 
    //here I want to update the grid 
    self.fetch(); 
    }; 
} 

你也可以做同樣的計算:

function vm(){ 
    var self = this; 

    self.items = ko.observableArray([]); 
    self.chosen_category = ko.observable(""); 

    self.fetch = function(){ 
    $.get('/api/items/' + self.chosen_category(), self.items); 
    }; 

    self.doStaff = ko.computed(self.fetch); 


    self.add_item = function() { 
    //here I want to update the grid 
    self.fetch(); 
    }; 
} 
+0

是的,這個解決方案有效,但如果我將來有更多的領域發送到服務器,我必須爲他們每個人添加訂閱。 –

+0

你可以用計算器做同樣的事情,在這種情況下,ko會自動訂閱函數中使用的所有觀察值。 –

+0

@AndrewLuzkovky我會建議明確這樣做,而不是通過計算。另外我認爲這不是發送虛擬機作爲請求的最好主意 - 你應該真的有一些其他對象來封裝查詢。此外,從REST服務返回JSON陣列是不是安全:http://incompleteness.me/blog/2007/03/05/json-is-not-as-safe-as-people-think-it-is/ – Stefan