2016-04-11 9 views
3

Model bir nesne listesi ise @Html.LabelFor model => model[i].member) boş bir for özniteliği oluşturur. DisplayName düzgün çalışıyor, model bağlama da gayet güzel çalışıyor. Çalışmıyor tek şey, for özniteliğidir. Aşağıda MVC kodunun iki versiyonu bulunmaktadır. İlk 3 kod parçacığı, çalışmayan model, denetleyici ve görünüm bileşimi içindir (model bir listedir). İkinci 3 kod parçacığı kümesi çalışır. Bu sefer liste bir nesneye sarılır.Jilet: Liste <> ve sonra @ Html.LabelFor boş "for" alanı oluşturursa, alan

Neyi eksik?

Modeli:

public class ViewModel { 
    public bool ClickMe { get; set; } 
} 

Denetleyici:

public ActionResult LabelForViewModel() { 
    List<ViewModel> model = new List<ViewModel>() { 
     new ViewModel() { ClickMe = true} 
    }; 
    return View(model); 
} 

Görünüm:

@model List<ModelBinding.Models.ViewModel> 
// form code removed for brevity 
@for (var i = 0; i < Model.Count; i++) { 
    <div class="form-group"> 
     @Html.LabelFor(model => model[i].ClickMe) 
     <div class="col-md-10"> 
      @Html.EditorFor(model => model[i].ClickMe, new { htmlAttributes = new { @class = "form-control" } }) 
      @Html.ValidationMessageFor(model => model[i].ClickMe, "", new { @class = "text-danger" }) 
     </div> 
    </div> 
} 

Biçimlendirme:

<div class="form-group"> 
    <label for="">ClickMe</label> 
    <div class="col-md-10"> 
     <input name="[0].ClickMe" class="form-control check-box" type="checkbox" checked="checked" value="true" data-val-required="The ClickMe field is required." data-val="true"><input name="[0].ClickMe" type="hidden" value="false"> 
     <span class="field-validation-valid text-danger" data-valmsg-replace="true" data-valmsg-for="[0].ClickMe"></span> 
    </div> 
</div> 

Lütfen alanın boş olduğunu ve girişin kimlik alanı olmadığını ("for" alanında) kullandığınızı unutmayın.

Nesnelerin listesini içeren, denetleyiciyi değiştirip görüntülenen ve sonra da gayet iyi çalışan bir sarıcı modeli oluşturdum. Bu durumda "for" alanı doğru şekilde doldurulur ve her şey beklendiği gibi çalışır.

public class ListWrapper { 
    public List<ViewModel> ViewModels { get; set; } 
} 

Görünüm:

@for (var i = 0; i < Model.ViewModels.Count; i++) { 
    <div class="form-group"> 
     @Html.LabelFor(model => model.ViewModels[i].ClickMe) 
     <div class="col-md-10"> 
      @Html.EditorFor(model => model.ViewModels[i].ClickMe, new { htmlAttributes = new { @class = "form-control" } }) 
      @Html.ValidationMessageFor(model => model.ViewModels[i].ClickMe, "", new { @class = "text-danger" }) 
     </div> 
    </div> 
} 

Biçimlendirme:

<div class="form-group"> 
    <label for="ViewModels_0__ClickMe">ClickMe</label> 
    <div class="col-md-10"> 
     <input name="ViewModels[0].ClickMe" class="form-control check-box" id="ViewModels_0__ClickMe" type="checkbox" checked="checked" value="true" data-val-required="The ClickMe field is required." data-val="true"><input name="ViewModels[0].ClickMe" type="hidden" value="false"> 
     <span class="field-validation-valid text-danger" data-valmsg-replace="true" data-valmsg-for="ViewModels[0].ClickMe"></span> 
    </div> 
</div> 

Yani, for nitelik modeli nesnelerin bir listesi yalnızca boş olduğu görülmektedir.

Bu bilinen bir sorun mu? Ya da belki bir şey özlüyorum?

cevap

2

Bu davranış, HTML-4 özelliklerine uyan çerçevenin sonucudur. HTML-4'te

İD NAME ve jeton ([A-Za-z]) bir harf ile başlamalıdır ve harf, rakam ([0-9]), tire herhangi bir sayıda (" takip edilebilir - "), alt çizgi (" _ "), iki nokta üst üste (": ") ve nokta (". ").

modeliniz topluluğudur ve yöntem özelliğinin adına göre name ve id özelliklerini oluşturur, form denetimlerini oluşturmak için @Html.EditorFor(m => m[i].SomeProperty) kullandığınızda. id özelliğini oluştururken Bu durumda koleksiyonunda ilk öğe için name nitelik jQuery selektörlü çatışmaları önlemek için ancak

name="[0].SomeProperty" 

olacak, yöntem bir alt çizgi _ ile ., [ ve ] karakterleri değiştirir ki

id="_0__SomeProperty" 

sonuçlanabilir ancak bu HTML-4 şartnamesine uygun geçersiz olduğu için, yardımcı html değil çıkış yapar olacaktır. ilişkili bir şekilde kontrol, bir id özelliği olmaz çünkü (@Html.LabelFor() kullanıldığında

de geçerlidir, for öz nitelik değeri html verilmez.

Not bu HTML-5, id özelliğinde geçerli olacak, bu yüzden umarım bu davranışı ileride atılır bir harfle başlayan ve bu nedenle geçerli değil "id="ViewModels_0__ClickMe çünkü

Kişisel ikinci örnek çalışır

Yan not:.. Sen çözebiliriz örneğin,

@Html.LabelFor(model => model[i].ClickMe, new { for = string.Format("item{0}", i) }) 
@Html.EditorFor(model => model.ViewModels[i].ClickMe, new { htmlAttributes = new { @class = "form-control", id = string.Format("item{0}", i) } }) 
+0

@GabrielLuci kendi id özelliklerini üreterek ilk sayısı, modeli Item' yüzden bu işe yaramaz 'adında bir özellik içermiyor ve hiçbir şeye –

+0

Evet bağlanan asla, bunu şimdi fark . [MSDN] (https://msdn.microsoft.com/en-us/library/0ebtbkkc (v = vs.110) .aspx? Cs-save-lang = 1 & cs-lang = csharp) bir 'Item' özelliği açıklar. ancak sadece indeksleyici ile görünür. –

+0

Linq kullanarak 'Model.ElementAt [i] .ClickMe' kullanabilir. Bu muhtemelen "ElementAt_0__ClickMe" gibi bir kimlik oluşturabilir, belki? Burada Linq kullanmak muhtemelen ideal değil. –

0

@model bildirimi, model nesnesini Model değişkenine atar (not 'M'). Ama sonra atanmamış olan model'dan okuyorsunuz.

bu deneyin: İkinci örnek hiç neden çalıştığını açıklamak, ama hey, bu bir deneyin vermez

@model List<ModelBinding.Models.ViewModel> 
    // form code removed for brevity 
     @for (var i = 0; i < Model.Count; i++) { 
      <div class="form-group"> 
       @Html.LabelFor(model => Model[i].ClickMe) 
       <div class="col-md-10"> 
        @Html.EditorFor(model => Model[i].ClickMe, new { htmlAttributes = new { @class = "form-control" } }) 
        @Html.ValidationMessageFor(model => Model[i].ClickMe, "", new { @class = "text-danger" }) 
       </div> 
      </div> 
     } 

.

İlgili konular