knockout for data applybindings knockout.js

knockout.js - for - knockout visible



Knockout.js: Enlace al objeto complejo (1)

Soy nuevo en knockout.js y estoy tratando de enlazar al siguiente objeto que representa un usuario:

{ "$id": "1", "$values": [ { "$id": "2", "Locations": { "$id": "3", "$values": [] }, "Photos": { "$id": "4", "$values": [] }, "UserId": 1, "Name": "Test User" } ] }

Un usuario puede cero o más ubicaciones, y cero o más fotos.

El modelo de vista:

function UsersViewModel() { var self = this; self.users = ko.observableArray(); var baseUri = ''http://localhost:46241/api/users''; $.getJSON(baseUri, function (data) { self.users = data; }); } $(document).ready(function () { ko.applyBindings(new UsersViewModel()); })

El HTML contiene el siguiente enlace:

<ul id="update-users" data-bind="foreach: users"> <li> <div><div class="item">User ID</div> <input type="text" data-bind="value: $data.UserId" /> </div> <div><div class="item">Name</div> <input type="text" data-bind="value: $data.Name" /> </div> </li> </ul>

¿Estoy completamente haciendo esto incorrectamente? ¿O las referencias de los objetos del usuario a Ubicaciones y Fotos posiblemente arruinan el enlace?


¿Estoy completamente haciendo esto incorrectamente?

Sí. Está sobrescribiendo su array observableArray en la devolución de llamada JSON, destruyéndolo así:

$.getJSON(baseUri, function (data) { self.users = data; });

En general, los observables knockout se asignan a este modo:

$.getJSON(baseUri, function (data) { self.users(data.$values); });

Tenga en cuenta que en su caso, data.$values parece contener la matriz real, no los data sí.

Esto funcionaría para su caso, pero no está usando el knockout en todo su potencial.

El plugin de mapeo se ha creado exactamente para este caso. Recursivamente atraviesa un objeto complejo y convierte todas sus propiedades en observables y todas las matrices contenidas en matrices observables. Esto le da un control detallado sobre el estado del objeto, lo que le permite controlar cada cambio.

$.getJSON(baseUri, function (data) { ko.mapping.fromJS(data.$values, {}, self.users); });

También permite actualizaciones parciales: suponga que recupera una lista de usuarios del servidor y su modelo de vista ya tiene la mitad de ellos. El complemento de mapeo es capaz de agregar solo aquellos a su modelo de vista que faltan y hacer los cambios apropiados a los existentes. Lea la sección "Uso avanzado" en los documentos si desea saber cómo hacerlo.

Suponiendo que obtiene una matriz de objetos de usuario del servidor y utiliza el complemento de asignación, su enlace se vería así:

<ul id="update-users" data-bind="foreach: users"> <li> <div><div class="item">User ID</div> <input type="text" data-bind="value: UserId" /> </div> <div><div class="item">Name</div> <input type="text" data-bind="value: Name" /> </div> <ul class="photos" data-bind="foreach: Photos.$values"> <!-- ... --> <ul> </li> </ul>

En general, el comentario de @Greg Smith es correcto. Intenta perder los $ en las teclas de objeto, pueden chocar con variables especiales en knockout en algún momento. Podría reemplazarlos de manera segura con guiones bajos, por ejemplo.

En una nota más general, trataría de eliminar la noción de $values $id / $values en su JSON si fuera usted, no parece servir para nada:

[ { "Locations": [], "Photos": [], "UserId": 1, "Name": "Test User" } ]