2010-12-13 14 views
5

Estoy creando una aplicación usando la biblioteca KnockoutJS, pero me he encontrado con un problema. En la página html, tengo un control simple <select> que quiero cargar con datos JSON devueltos por un servicio web.ObservableArray que no refleja la actualización de datos

I definen la matriz observable como sigue:

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

Cuando se carga la página, se hace la llamada ajax y se devuelven los datos. En la devolución de llamada, hago lo siguiente:

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

basado en los documentos KO, yo esperaría que iba a establecer el resultado como este:

laborRow.positions(msg); 

Sin embargo, eso sólo genera un error que indica que "laborRow.positions en no una función"

la plantilla en el HTML es como sigue:

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

El objeto laborRow es una propiedad en ViewModel que está vinculada a la página. Por alguna razón, esto no funciona. Para agregar otra arruga, si agrego un código para echar un vistazo en el Array observable e imprimo algún dato, los datos están ahí. Por lo tanto, se está cargando con éxito.

Cualquier pensamiento sería muy apreciado.

El código completo para mi ejemplo de 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** 
      }, 

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

Por último, gracias a los comentarios de Sean abajo, yo era capaz de conseguir que funcione mediante la modificación del código en la devolución de llamada de la siguiente manera:

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

Respuesta

5

El problema es que no ha creado realmente su modelo:

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

Cambiar la función de un objeto desnudo (como se muestra en la Knockout docs):

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

y usted será capaz de llamar laborRow.positions(msg); para que funcionen.


EDITAR

Basado en el nuevo código, laborRow todavía no se instancia - si está configurando var laborRow otra parte de su código (alrededor de la petición Ajax, tal vez), entonces usted querrá para asegurarse de que su pila de llamadas es el siguiente:

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

me ha picado las "variables ko son getters no attributes" error en varias ocasiones ... ¿podría estar sucediendo eso con tu código?

+0

Gracias por la respuesta Sean. Yo he creado el modelo. En el viewModel real, tengo un Array observable que, cuando se crea, comienza la vida con un nuevo objeto de trabajoRow como tal: this.laborLine = ko.observableArray ([new laborRow()]); – Alex

+0

@Alex - excelente ... ¿podrías publicar un poco más de tu código entonces? Como lo describe, actualmente todo * debería * estar funcionando. –

+0

@Alex - respuesta actualizada para hacer otra puñalada. –

Cuestiones relacionadas