Создайте объект со списком свойств и передайте его в контроллер - PullRequest
0 голосов
/ 14 февраля 2012

Возможно, есть простое решение для моей проблемы, но я просто не могу его найти. Я прочитал много уроков о Knockout, поэтому я получаю основы, но я задаю этот вопрос, потому что моя структура сущности немного сложнее, чем человек с именем и списком друзей, которые могут быть или не быть в Твиттере (Видео на канале 9: , помогающее создавать динамические пользовательские интерфейсы JavaScript с MVVM и ASP.NET ) . Вот моя ситуация:

У меня есть класс PersonnelClass с этой базовой структурой:

[Serializable]
//The interface is for the implementation of 'Name' and 'Description'
public class PersonnelClass : IPersonnelClassOrPerson 
{
    public PersonnelClass() : this(Guid.NewGuid(), "", "") { }

    public PersonnelClass(Guid id, String name, String description = null)
    {
        if (id == Guid.Empty) { throw new ArgumentNullException("id"); }
        Id = id;
        Name = name;
        Description = description;
        Properties = new PropertyCollection();
    }

    public Guid Id { get; private set; }
    public String Name { get; set; }
    public String Description { get; set; }
    public PropertyCollection Properties { get; private set; }
}

Класс PropertyCollection класс и связанный с ним AbstractProperty класс выглядит следующим образом:

[Serializable]
public class PropertyCollection: List<AbstractProperty> { }

[Serializable]
public abstract class AbstractProperty: IEntity, IProperty
{
    public AbstractProperty(String name, String description = null) : this(Guid.NewGuid(), name, description) { }

    public AbstractProperty(Guid id, String name, String description = null)
    {
        if (id == Guid.Empty) { throw new ArgumentNullException("id"); }
        if (String.IsNullOrEmpty(name)) { throw new ArgumentNullException("name"); }
        Id = id;
        Name = name;
        Description = description;
    }

    public Guid Id { get; private set; }
    public String Name { get; private set; }
    public String Description { get; private set; }
}

В моем контроллере я создаю экземпляр PersonnelClassViewModel , который имеет такую ​​структуру:

public class PersonnelClassViewModel
{
    public PersonnelClass PersonnelClass { get; set; }
    public List<AbstractProperty> Properties { get; set; }
}

Я заполняю эту модель представления новым PersonnelClass и двумя тестовыми свойствами, чтобы передать в мой просмотр следующим образом:

var properties = new List<AbstractProperty>
{
    new TextProperty("prop1", "descr1"),
    new TextProperty("prop2", "descr2")
    //TextProperty is derived from AbstractProperty
};
var vm = new PersonnelClassViewModel { Properties = properties };
return View(vm);

Я получаю все в моем представлении, как я хотел. В представлении я хочу создать новый PersonnelClass с набором выбранных свойств. У меня есть поля для Name и Description, и для добавления свойств у меня есть ListBox с уже существующими свойствами (для демонстрационной цели они пришли из контроллера сейчас). С помощью небольшого кода JavaScript Knockout я могу выбрать элементы из этого списка и заполнить HTML-select-control () выбранными свойствами для добавления в PersonnelClass. Это все работает нормально, пока я не хочу создать объект для передачи обратно в контроллер и создать PersonnelClass.

Мой вопрос: какой код JS Knockout необходим для создания этого объекта и передачи его в контроллер, отправив форму и в моем контроллере, как я должен получить этот объект, что означает: какой тип объект должен быть (PersonnelClass, PersonnelClassViewModel, ...)?

Если вам нужна дополнительная информация / код, пожалуйста, спросите. Заранее спасибо!

Обновление после ответа «B Z»:

Я следовал еще нескольким учебникам Стивена Сандерсона по этому поводу, чтобы убедиться, что я понимаю это, особенно тот, который вы предоставили в своем ответе. Теперь у меня есть следующий код в моем представлении, чтобы начать с:

var initialData = @Html.Raw(new JavaScriptSerializer().Serialize(Model));

var viewModel = {
    personnelClassViewModel : ko.mapping.fromJS(initialData),
    properties : personnelClassViewModel.Properties,
    selectedProperties : ko.observableArray([]),
    addedProperties : ko.observableArray([])
};

ko.applyBindings(viewModel);

Переменная 'initialData' содержит значения, которые я ожидаю получить, но затем я получаю следующую ошибку:

Ошибка времени выполнения Microsoft JScript: «staffClassViewModel» не определен

Понятия не имею. Может кто-нибудь помочь мне это исправить?

1 Ответ

1 голос
/ 14 февраля 2012

У Стивена Сандерсона есть пример того, как работать со списками переменной длины и knockoutjs

http://blog.stevensanderson.com/2010/07/12/editing-a-variable-length-list-knockout-style/

Сказав это, я думаю, что ваша проблема не столько в нокаутеи многое другое о том, как правильно связать данные на стороне сервера.В приведенной выше ссылке Стивен использует атрибут FromJson для привязки модели, который может оказаться полезным ...

HTH

...