次の C# AjaxViewModel モデルを渡しています。
namespace Db.ViewModels
{
public class DbAjaxViewModel
{
public DbAjaxViewModel() {
Products = new List<DbProductViewModel>();
}
public List<DbProductViewModel> Products { get; set; }
}
public class DbProductViewModel
{
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Price { get; set; }
public string CategoryId { get; set; }
}
}
..次のコードで:
[HttpGet]
public ActionResult GetProductsAjax() {
var viewModel = _service.GetAllProductsAjaxViewModel();
return new JsonResult { Data = viewModel, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
次に、ko マッピングを行います。
function callBack(result) {
sprAdmin.product.viewModel = ko.mapping.fromJS(result);
ko.applyBindings(sprAdmin.product.viewModel, $("adminProductWrap")[0]);
}
$.ajax({
type: "GET",
url: url,
success: callBack
});
そしてそれはうまく機能します。ビューモデルに空のアイテムを追加するこの関数があります:
addProduct: function () {
function product() {
this.Id = ko.observable("-1");
this.CategoryId = ko.observable("0");
this.Name = ko.observable("");
this.Description = ko.observable("");
this.Price = ko.observable("0");
}
debug.debug("adding new product");
sprAdmin.product.viewModel.Products.push(new product());
var debugArray = sprAdmin.product.viewModel.Products(),
debugData = debugArray[debugArray.length - 1];
debug.debug("id: " + debugData.Id() + ", name: " + debugData.Name() + ", description: " + debugData.Description() + ", price: " + debugData.Price() + ", categoryId: " + debugData.CategoryId());
}
ご覧のとおり、debug.debug は Products() 配列の最後の項目を取得し、その内容を表示します。これもうまく機能します。
しかし。
空の配列に複数の項目を追加して var data = ko.mapping.toJSON(viewModel); を実行すると、debug.debug("ajax 送信データ: " + データ);
次のように、JSON に変換されたマップされていない viewModel の内容を示します。
{"Products":[{"Id":"1","CategoryId":"0","Name":"name","Description":"desc","Price":"0"},{}]}
Products 配列の 2 番目 (存在する場合はさらに) の項目は完全に空です。常に最初のアイテムに対してのみ機能します。
助けてください。
===
解決:
まず、observableArray を宣言する必要があります。
viewModel: {
Products: ko.observableArray([])
}
次に、次のようにマッピングします。
sprAdmin.product.viewModel.Products(ko.mapping.fromJS(result.Products)());