No ObservableArray que refleja la actualización de datos
-
09-10-2019 - |
Pregunta
Estoy creando una aplicación utilizando la biblioteca KnockoutJS muy pulido, pero me he encontrado con un obstáculo. En la página html, tengo un control <select>
claro que quiero cargar con datos JSON devueltos desde un servicio web.
I definir 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;
}
sobre la base de los documentos KO, yo esperaría que iba a establecer el resultado como este:
laborRow.positions(msg);
Sin embargo, eso sólo arroja un error que indica que "en laborRow.positions 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 el modelo de vista que está ligado a la página. Por alguna razón, esto no funciona. Para añadir otra arruga, si agrego código para vistazo a la observableArray e imprimir alguna pieza de datos, los datos están ahí. Por lo que está siendo cargado con éxito.
Cualquier pensamiento sería muy apreciada.
El código completo para mi caso de ejemplo:
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 código 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);
}
Solución
El problema es que no se 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);
y hacer que funcione.
Editar
Con base en el nuevo código, laborRow
todavía no se crea una instancia - si está configurando var laborRow
otra parte de su código (alrededor de la petición Ajax, tal vez), entonces usted querrá asegurarse de que sus Pila de llamadas es similar al 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
he sido mordido por las "variables ko son getters
no attributes
" error en varias ocasiones ... podría ser que sucedía con su código?