utils unwrapobservable tojs knockout from javascript json ajax knockout.js

javascript - unwrapobservable - ko tojs



cargando un knockout.js observableArray() desde la llamada.ajax() (5)

Esto me desconcierta. Debe ser algo pequeño que no estoy viendo. Estoy intentando cargar un Array observableArray muy simple en un nocaut con una llamada ajax.

javascript

// we bind the array to the view model property with an empty array. var data = []; var viewModel = { vendors: ko.observableArray(data) }; ko.applyBindings(viewModel); $(function () { // on this click event, we popular the observable array $(''#load'').click(function () { // WORKS. Html is updated appropriately. viewModel.vendors([{ "Id": "01" },{ "Id": "02" },{ "Id": "03" }]); // DOES NOT WORK. Fiddler2 shows the same exact json string come back // as in the example above, and the success function is being called. $.ajax({ url: ''/vendors/10'', dataType: ''json'', success: function (data) { viewModel.vendors(data); } }); }); });

html

<button id="load">Load</button> <ul data-bind="template: { foreach: vendors }"> <li><span data-bind="text: Id"></span></li> </ul>

Pregunta: ¿Por qué la llamada ajax exitosa, cuyo valor de variable de data coincide con byte por byte con el valor de tipo duro, no activa la actualización de html?


Creo que este es un error. La muestra de Knockout funciona cuando la usamos con la clase wrapper:

public class ResultWrapper { public Title {get;set;} public List<Result> {get;set;} }

http://learn.knockoutjs.com/#/?tutorial=webmail

Pero si devolvemos los resultados directamente, no hay forma de enlazarlos. (sin aplicar los enlaces adicionales)


Esto es lo que hice en mi aplicación MVC .net con knockout y jquery.

// Scripts/groItems.js (function () { var ViewModel = function () { items = ko.observableArray(), ItemName = ko.observable(), Img = ko.observable(), Qty = ko.observable() } $.getJSON(''/Items2/AllItems'', function (data) { for (var i = 0; i < data.length; i++) { self.items.push(data[i]); } }); var vm = new ViewModel(); $(function () { ko.applyBindings(vm); }); }());

@model IEnumerable<GroModel.Item> @{ ViewBag.Title = "Index"; } <p> @Html.ActionLink("Create New", "Create") </p> <div data-bind="text: items().length"></div> <table class="container table table-hover"> <thead> <tr> <th>Item name</th> <th>img</th> <th>qty</th> </tr> </thead> <tbody data-bind="foreach: items"> <tr> <td data-bind="text: ItemName"></td> <td data-bind="text: Img"></td> <td data-bind="text: Qty"></td> </tr> </tbody> </table> @section Scripts { <script src="~/Scripts/knockout-3.4.2.js"></script> <script src="~/Scripts/groItems.js"></script> }

Lo siguiente es parte de mi código en el Items2Controller.cs

private GroContext db = new GroContext(); public JsonResult AllItems() { return Json(db.Items.ToList(), JsonRequestBehavior.AllowGet); }

Espero que esto ayude. Gracias


No hay razón para que esto no funcione bien. Como esto demuestra.

http://jsfiddle.net/madcapnmckay/EYueU/

Me gustaría comprobar que la publicación ajax en realidad está devolviendo datos json y que json es una matriz y que se está analizando correctamente.

Tuve que modificar la llamada ajax para que los manejadores ajax del violín funcionaran correctamente.

Nada más se me ocurre.

Espero que esto ayude.


Podemos usar una función de utilidad de JavaScript simple como una solución alternativa.

En lugar de viewModel.vendors(data); , envolver con eval (investigue los peligros de eval primero) funcionará.

eval("viewModel.vendors("+JSON.stringify(data)+");");


var self=this; //var self first line in model $.ajax({ url: ", dataType: "json", contentType: ''application/json'', type: "POST", data: JSON.stringify({ }), processdata: true, beforeSend: function () { $.mobile.loading(''show''); }, error: function (xhr, textStatus, errorThrown) { alert(''Sorry!''); }, success: function (data) { $.mobile.loading(''hide''); if (data.result!= '''') { self.vendors(data.result); } else { self.vendors({something}); } } });

Utilice self.vendors no este viewModel.vendors