2010-12-13 13 views
5

Tworzę aplikację przy użyciu bardzo zgrabnej biblioteki KnockoutJS, ale natknąłem się na przeszkodę. Na stronie html mam zwykły kontrolkę <select>, którą chcę załadować z danymi JSON zwróconymi z usługi WWW.ObservableArray nie odzwierciedla aktualizacji danych

zdefiniować obserwowalnym tablicę następująco:

var laborRow = function() { 
    this.positions = ko.observableArray([]); 
}; 

Po załadowaniu strony, wywołanie ajax jest wykonany, a dane są zwracane. W zwrotnego, I wykonaj następujące czynności:

success: function (msg) { 
     laborRow.positions = msg; 
    } 

podstawie docs Ko, bym się spodziewał, że będę ustawić wynik takiego:

laborRow.positions(msg); 

jednak, że tylko zgłasza błąd informujący, że "laborRow.positions w nie funkcji"

szablonu w html jest następująca:

<tbody data-bind='template: {name: "laborRowTemplate", foreach: laborLine}'> </tbody> 
</div> 
    <script type="text/html" id="laborRowTemplate"> 
     <tr> 

      <td><select data-bind='options: positions, optionsText: "Title", optionsCaption: "select", value: selectedPosition '></select></td> 

     </tr> 
    </script> 

Obiekt laborRow jest właściwością modelu ViewModel, który jest powiązany ze stroną. Z jakiegoś powodu to nie działa. Aby dodać kolejną zmarszczkę, jeśli dodam kod do podglądu w observableArray i wydrukuję jakiś fragment danych, dane tam są. Jest ładowany pomyślnie.

Wszelkie przemyślenia będą mile widziane.

Kod pełna za moim przykładem postępowania:

var laborRow = function() { 
    this.positions = ko.observableArray([]);  
}; 

var projectEstimate = function() { 
    this.laborLine = ko.observableArray([new laborRow()]); 

}; 

var projectViewModel = new projectEstimate(); 
ko.applyBindings(projectViewModel); 

//and the code in the callback function on ajax success 

success: function (msg) { 
       laborRow.positions = msg; 
       //laborRow.positions(msg); **this does not work - error is laborRow.positions is not a function** 
      }, 

a HTML:

<tbody data-bind='template: {name: "laborRowTemplate", foreach: 
laborLine}'> </tbody> 

    <script type="text/html" id="laborRowTemplate"> 
     <tr> 
      <td><select data-bind='options: positions, optionsText: 
"Title", optionsCaption: "select", value: selectedPosition '></ 
select></td> 

     </tr> 
    </script> 

Wreszcie, dzięki komentarzach Seana poniżej, udało mi się dostać pracy, modyfikując kod wywołanie zwrotne:

success: function (msg) { 
    projectViewModel.laborLine()[(projectViewModel.laborLine().length-1)].positionList(msg); 
} 

Odpowiedz

5

Problem polega na tym, że nie stworzyłeś modelu:

var laborRow = function() { 
    this.positions = ko.observableArray([]); 
    // will only be called if you call var some_var = new laborRow() 
}; 

Zmień swoją funkcję do gołej obiektu (jak pokazano w Knockout docs):

var laborRow = { 
    positions: ko.observableArray([]) 
}; 

I będziesz mógł zadzwonić laborRow.positions(msg); i mają działać.


EDIT

oparciu o nowy kod, laborRow nadal nie jest instancja - jeśli ustawienie var laborRow gdzieś indziej w kodzie (wokół żądania ajax, być może), a następnie będziemy chcieli aby upewnić się, że stos wywołań wygląda następująco:

projectViewModel.laborLine()[0].positions() 
// This will return the array you're looking for. 
// The key is that laborLine is a `getter` not an attribute 

byłem ugryziony przez „zmiennych ko są getters nie attributes” bug kilkakrotnie ... może to się dzieje z twoim kodem?

+0

Dzięki za odpowiedź Seana. Stworzyłem model. W rzeczywistym viewModelu, mam obserwowalną tablicę, która po utworzeniu rozpoczyna życie od nowego obiektu workRow jako takiego: this.laborLine = ko.observableArray ([new laborRow()]); – Alex

+0

@Alex - doskonałe ... czy mógłbyś wtedy dodać trochę więcej swojego kodu? Jak to opisujesz, obecnie wszystko * powinno * działać. –

+0

@Alex - zaktualizowano odpowiedź, aby dokonać kolejnego ukłucia. –

Powiązane problemy