2012-12-12 10 views
6

Mam siatkę i kontrolkę wyboru na stronie. Wybranie dowolnej wartości wyzwala aktualizację siatki. Że aktualizacja odbywa się za pomocą obliczeń. Czy mogę ręcznie uruchomić siatkę, aby zaktualizować, powiedzmy, w sytuacji, gdy nowa wartość zostanie dodana do siatki?Knockout.js: wyzwalacz ręczny obliczony

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 
     }; 
} 

Oczywiście mogę przenieść go do oddzielnej funkcji, ale szukam czystszego rozwiązania. Dzięki!

wersja robocza:

  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

nie musisz go aktualizować ręcznie od pozycji jest observableArray. Ale nie jestem pewien, czy podoba mi się sposób, w jaki korzystasz z obliczeniowych obserwowalnych. – Anders

+0

Myślę, że pomysł KnockOut polega na tym, że robisz rzeczy obserwowalne, a nie samemu wyzwalasz. Metoda pobierania powinna być automatycznie wywoływana przez zmianę kolekcji. Szukam jak, czy masz pełniejszy przykład? – EricG

Odpowiedz

9

Lepiej jest to zrobić z subscription zamiast computed. W takim przypadku można zdefiniować funkcję sprowadzić do wykorzystania zarówno abonamentu i ręcznego połączenia:

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(); 
    }; 
} 

Również można zrobić to samo z obliczane:

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

Tak, to rozwiązanie działa, ale jeśli mam zamiar mieć więcej pól w przyszłości, aby wysłać je do serwera, muszę dodać subskrypcję dla każdego z nich. –

+0

Możesz zrobić to samo z obliczonym, w takim przypadku ko automatycznie zasubskrybuje wszystkie obserwowalne używane w funkcji. –

+0

@AndrewLuzkovky Proponuję zrobić to wyraźnie, a nie przez obliczenia. Myślę też, że nie jest najlepszym pomysłem wysłanie vm jako żądania - powinieneś naprawdę mieć jakiś inny obiekt do enkapsulacji zapytania. Co więcej, zwracanie tablic JSON z usługi REST nie jest bezpieczne: http://incompleteness.me/blog/2007/03/05/json-is-not-as-safe-as-people-think-it-is/ – Stefan