おそらく私の問題には簡単な解決策がありますが、私はそれを見つけることができないようです。ノックアウトに関するチュートリアルをたくさん読んだので、基本を理解しましたが、私のエンティティ構造は、Twitterにある場合とない場合がある名前と友達のリストを持つ人よりも少し複雑なので、この質問をします(ビデオChannel9:MVVMとASP.NETを使用して動的なJavaScript UIを構築するのに役立ちます)。これが私の状況です:
この基本構造を持つクラス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と2つのテストプロパティを入力して、次のようにビューに渡します。
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を作成します。名前と説明のフィールドがあり、プロパティを追加するために、既存のプロパティを含むリストボックスがあります(デモ用に、これらはコントローラーから取得されました)。Knockout JavaScriptコードを少し使用することで、このリストからアイテムを選択し、HTML select-control()に選択したプロパティを入力してPersonnelClassに追加できます。これはすべて正常に機能しますが、オブジェクトを作成してControllerに戻し、PersonnelClassを作成するまでは問題ありません。
私の質問は、このオブジェクトを構築し、フォームを送信してコントローラーに渡すために必要なKnockout JSコードと、コントローラーでこのオブジェクトを受け取る方法、つまり、これがどのタイプのオブジェクトであるか(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ランタイムエラー:「personnelClassViewModel」は未定義です
もう手がかりがありません。誰かが私がこれを修正するのを手伝ってもらえますか?