2013-07-15 2 views
1

У меня есть простой MVC модель, как это:Нокаут отображение простой объект

public class User 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string MobileNumber { get; set; } 
    public string EmailAddress { get; set; } 
} 

Я хотел бы отобразить один объект этого типа внутри нокаута ViewModel для того, чтобы заполнить ее:

var UserViewModel = function() { 
    var self = this; 
    self.user = ko.mapping.fromJS({}); 
    $.getJSON("/UserManagement/CreateEmptyUser", function (data) { 
     ko.mapping.fromJS(data, self.user); 
    }); 
    self.createUser = function (data, eventArgs) { 
     var user = data; 
     $.ajax({ 
      type: "post", 
      contentType: "application/json", 
      data: ko.toJSON(user), 
      url: "@Url.Action("CreateUser")", 
      success: function() { 
       window.location = "@Url.Action("AddNew")"; 
      } 
     }); 
    }; 
}; 

Проблема, с которой я сталкиваюсь, заключается в том, что я не знаю, как сопоставить любой объект. Я попытался с помощью

self.user = ko.mapping.fromJS([]); 
$.getJSON("/UserManagement/CreateEmptyUser", function (data) { 
     ko.mapping.fromJS(data,{}, self.user); 
    }); 

, который используется для массивов и пытается извлечь элемент с индексом 0, то другое решение, я думал, что будет работать это один во 2-м блоке комментариев. Все, что я нашел в google, привело меня к отображению целых массивов, но ничего не касалось простого сопоставления объектов. Есть ли правильный способ сделать это? Я хотел бы оставить модель разделенной, а не вручную описывать ее свойства в javascript.

Спасибо, Alex Barac

ответ

3

Я думаю, ваша проблема в том, что вы используете отображение способа создать экземпляр модели вида, который не даст ему никаких свойств, поэтому при попытке отобразить данные после JSON call, нет свойств для self.user для заполнения. Либо создать свой пользовательский объект со свойствами, которые вы хотите там, либо использовать mapping.fromJS, чтобы создать свой ViewModel в первую очередь:

self.user = { FirstName: ko.observable(''), etc... } 

и оставить отображение линии, как это, или

self.user; 
$.getJSON("/UserManagement/CreateEmptyUser", function (data) { 
    self.user = ko.mapping.fromJS(data); 
} 
+0

Спасибо за предложения. Я попробовал свой второй метод, но 'self.user' остается неопределенным после вызова метода' $ .getJSON'. Я попытался установить 'self.user = null;', но после вызова значение остается «null». Думаю, осталось только вручную отобразить свойства. –

+0

Обычно я использую первый метод, если честно, поскольку я могу сразу применить Bindings на загрузке страницы, что полезно, когда у вас есть модели детского просмотра, которые вы не хотите связывать индивидуально.Вы также можете попробовать передать пустое отображение на карту: ko.mapping.fromJS (data, {}); и посмотреть, работает ли это. –

+0

Он работает с первым методом, спасибо :) –

0

Я продолжал работать и проверять это, и я нашел решение, которое я хотел в начале. Идея использует предложение @Paul Manzotti «s,

self.user; 
$.getJSON("/UserManagement/CreateEmptyUser", function (data) { 
    self.user = ko.mapping.fromJS(data); 
} 

, но заменяя self.user; с self.user={}; и

self.user = ko.mapping.fromJS(data) 

с

ko.mapping.fromJS(data,{},self.user); 

При использовании этого нет необходимости вручную объявить свойство каждого объекта в viewmodel. Надеюсь, это будет полезно для тех, кто наткнулся на ту же проблему.

0

Если ваш viewModel, о котором идет речь, должен быть сам наблюдаемым, я обнаружил, что использовать отображение для возврата наблюдаемого массива в качестве упомянутого OP, а затем возвращает первый элемент в этом массиве. Это также полезно для возврата одного объекта в ajax, который затем вы хотите нажать на существующий наблюдаемый массив. У меня есть вспомогательная функция для этого:

koMappingUsingArray = function (jsObject, mapping) { 
    var observableObjectArray = ko.observableArray(); 
    var objectArray = new Array(jsObject); 
    ko.mapping.fromJS(objectArray, mapping, observableObjectArray); 

    return observableObjectArray()[0]; 
}; 

, а затем вызвать его, такие как:

self.myObject = ko.observable(); 

    $.ajax({ 
     type: "POST", 
     url: "....", 
     data: ko.mapping.toJSON(???), 
     contentType: "application/json; charset=utf-8", 
     success: function (returnedObject) { 
      self.myObject (koMappingUsingArray(returnedObject)); 
     }); 
Смежные вопросы