2010-12-13 3 views
5

Sto creando un'app utilizzando la libreria KnockoutJS molto liscia, ma ho incontrato un problema. Nella pagina html, ho un semplice controllo <select> che voglio caricare con i dati JSON restituiti da un servizio web.ObservableArray non riflette l'aggiornamento dei dati

definisco matrice osservabile come segue:

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

Al caricamento della pagina, la chiamata ajax è fatto ei dati vengono restituiti. Nella richiamata, faccio la seguente:

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

sulla base dei documenti KO, mi sarei aspettato che vorrei impostare il risultato come questo:

laborRow.positions(msg); 

tuttavia, che solo genera un errore che indica che "laborRow.positions in non una funzione"

il modello in html è la seguente:

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

L'oggetto laborRow è una proprietà sul ViewModel associato alla pagina. Per qualsiasi motivo, questo non funziona. Per aggiungere un'altra ruga, se aggiungo il codice per dare un'occhiata all'array observable e stampare alcuni dati, i dati sono lì. Quindi viene caricato con successo.

Ogni pensiero sarebbe molto apprezzato.

Il codice completo per il mio esempio caso:

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** 
      }, 

E l'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> 

Infine, grazie ai commenti di Sean sotto, sono stato in grado di farlo funzionare modificando il codice in il callback come segue:

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

risposta

5

il problema è che non si è di fatto creato il vostro modello:

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

Cambia la funzione di un oggetto nudo (come mostrato nella Knockout docs):

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

e sarete in grado di chiamare laborRow.positions(msg); e farlo funzionare.


EDIT

Sulla base del nuovo codice, laborRow non è ancora istanziato - se si sta impostando var laborRow da qualche altra parte nel codice (circa la richiesta ajax, forse) allora si vorrà per assicurarsi che il vostro stack di chiamate è simile al seguente:

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

sono stato morso da "variabili ko sono getters non attributes" bug in diverse occasioni ... potrebbe succedere questo con il tuo codice?

+0

Grazie per la risposta Sean. Ho creato il modello. Nell'effettivo viewModel, ho un ObservableArray che, una volta creato, inizia la vita con un nuovo oggetto labourRow come tale: this.laborLine = ko.observableArray ([new labyrow()]); – Alex

+0

@Alex - eccellente ... potresti pubblicare un po 'più del tuo codice allora? Come lo descrivi attualmente tutto dovrebbe * funzionare *. –

+0

@Alex - risposta aggiornata per fare un altro tentativo. –