2012-07-14 14 views
11

Düzenleyici Şablonu dinamik bir özellik ile çalışmak için çalışıyoruz - hiçbir boşuna. Belki biriniz bize yardım edebilir.Asp.Net MVC 3 Dinamik özellik için düzenleme

public class Criterion 
{ 
    ... 
    public string Text { get; set; } 
    public dynamic Value { get; set; } 
    public Type Type { get; set; } 
    ... 
} 

Bizim jilet görünümü her İçinde kriterler listesini içeren bölümlerinin bir listesini containg bir model alır: Burada

kabaca bizim sınıftır. (Biz zamanında bu infos olsun.) Bütün bu kriterler düzenleme modunda görüntülenmesi gereken - gerçek tipine ilişkin: (alıntı)

@for (int i = 0; i < model.Sections.Count(); i++) 
{ 
    for (int j = 0; j < model.Sections[i].Criteria.Count(); j++) 
    { 
     var criterion = model.Sections[i].Criteria[j]; 
     var type = criterion.Type.Name; 
     var name = "Sections[" + i + "].Criteria[" + j + "].Value"; 
     var criterionDisplayName = criterion.Text; 
     <label for="[email protected](i)[email protected](j)__Value">@criterionDisplayName</label> 
     @Html.Editor(name, type) 
    } 
} 

Bu, örneğin ekran bir onay kutusu doğru, ama bu değeri kullanmaz gelmez onay kutusu durumunu doğru olarak ayarlamak için (ölçüt.Value doğruysa işaretliyse). Aynı şey ints gibi diğer türler için de geçerlidir. (POST isteğinden sonra formu doğru bir şekilde doldurur, ancak bunun nedeni MVC'nin kullanıcı girdisini yeniden oluşturmak için geçici bir model kullanmasıdır.)

Denediğimiz ve araştırdığımız kadar: Düzenleyicisi kullanmak bile mümkün mü? tip dynamic özellikli şablon? Eğer evetse - nasıl çalışırız? (Biz olası türüne göre ayırt etmek istemeyiz. Biz gerçek tipine göre doğru Editor şablonunu kullanmak için MVC framework olması istiyorum.)

cevap

15

Dynamics ASP.NET ile güzel bir şekilde uygun değildir. MVC. Bana ViewBag'u hatırlatıyorlar ve vücudumun çok derin kumaşlarından ViewBag nefret ediyorum. Bu yüzden farklı bir yaklaşım alırdım.

s örneğin şu modelini alalım:

public class Criterion 
{ 
    public string Text { get; set; } 
    public object Value { get; set; } 
} 

Değeri işlemek isteyen herhangi bir tipte olabilir. Eğer karşılık gelen editör tanımlayabiliriz işlemek istediğiniz her tür için Şimdi

@model IList<Criterion> 

@using (Html.BeginForm()) 
{ 
    for (int i = 0; i < Model.Count; i++) 
    { 
     <div> 
      @Html.LabelFor(x => x[i], Model[i].Text) 
      @Html.EditorFor(x => x[i].Value, "Criterion_" + Model[i].Value.GetType().Name) 
     </div> 
    } 

    <button type="submit">OK</button> 
} 

:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     var model = new[] 
     { 
      new Criterion { Text = "some integer", Value = 2 }, 
      new Criterion { Text = "some boolean", Value = true }, 
      new Criterion { Text = "some string", Value = "foo" }, 
     }; 
     return View(model); 
    } 
} 

ve sonra karşılık gelen görünümü:

Şimdi bu modeli doldurur bir denetleyici olabilir şablon:

~/Views/Shared/EditorTemplates/Criterion_String.cshtml:

:

@model bool 
@Html.CheckBoxFor(x => x) 

~/Views/Shared/EditorTemplates/Criterion_Int32.cshtml:

@model int 
@{ 
    var items = Enumerable 
     .Range(1, 5) 
     .Select(x => new SelectListItem 
     { 
      Value = x.ToString(), 
      Text = "item " + x 
     }); 
} 

@Html.DropDownListFor(x => x, new SelectList(items, "Value", "Text", Model)) 

Açıkçası görünümünde bu modeli sergileyen tek bir ilk adımdır. Bazı işlemlerde kullanıcının POST denetleyici eylemine geri döndürdüğü değerleri almak istediğinizi varsayalım. Bu durumda, bazı küçük uyarlamalar gereklidir. Çalışma zamanında doğru türü başlatabilecek ve her bir satır için beton türünü gizli alan olarak içerebilecek özel bir model bağlayıcı eklemeliyiz. Zaten this post'da bir örnek gösterdim. Ayrıca bu örnekte, object türüyle doğrudan çalışmak yerine bir temel sınıf kullandığımı da unutmayın.

+0

Güçlü yazılan görünümle çalışır.Dizin Görünümünü güçlü yazılan görünümü kullanmamak için değiştirmeyi denedim: Silindi 'lodel IList ' ve '@ {var model = (IList ) Modeli; } '. Sonra @ Html.Editor ("model [" + i + "] .Value", "Criterion_" + model [i] .Value.GetType(). Name) 'ı deneyin, ama bana bir hata verir - _The model Sözlüğe aktarılan öğe boştur, ancak bu sözlük 'System.Int32' türünde boş olmayan bir model öğesi gerektirir. Ne yanlış yapıyorum? Hata ayıklama bana GetType() adını gösterir. – toni

+0

Bu arada, güçlü bir şekilde yazılmamış görünümü kullanmamız gerekiyor çünkü üçüncü parti bir çerçeve kullanıyoruz (Orchard'dan ContentShape). – toni

+0

Yukarıdaki gibi Darins yaklaşımını 'object' ile bitirdik. Dinamik ViewModel'i yayınlamak ve güçlü bir şekilde yazılmış bir editör şablonuna aktarmak zorunda kaldık. Teşekkürler, Darin, değerli girdiler için. – toni