Javascript'ten MVC'nin model özelliğine erişme


148

Benim görünüm modelime sarılmış aşağıdaki modele sahibim

public class FloorPlanSettingsModel
{
    public int Id { get; set; }
    public int? MainFloorPlanId { get; set; }
    public string ImageDirectory { get; set; }
    public string ThumbnailDirectory { get; set; }
    public string IconsDirectory { get; set; }
}

Javascript'ten yukarıdaki özelliklerden birine nasıl erişirim?

Bunu denedim, ama "tanımsızım"

var floorplanSettings = "@Model.FloorPlanSettings";
alert(floorplanSettings.IconsDirectory);

5
Açık olmak gerekirse, JavaScript değişkeninin değerini, o sınıfın (dize) .ToString () değeri olacak olan C # değişkeni "Model.FloorPlanSettings" değerine ayarlıyorsunuz. Ardından, yeni oluşturduğunuz JavaScript dize değişkeninde "IconsDirectory" adlı bir JavaScript özelliğini uyarmaya çalışıyorsunuz. Bir JavaScript dizesinde "IconsDirectory" özelliği bulunmadığından tanımsız hale gelirsiniz.
Joel Cochran

Tam bir Test örneği sağladı ve javascript değişkenine Model verileri atamanın tüm senaryolarını açıkladı
Rajshekar Reddy

Bu görünüm (cshtml) dışında çalışmaz. yani görünüm tarafından referans verilen harici bir .js dosyasında.
Spencer Sullivan

Yanıtlar:


240

Tüm sunucu tarafı modelinizi alıp aşağıdakileri yaparak bir Javascript nesnesine dönüştürebilirsiniz:

var model = @Html.Raw(Json.Encode(Model));

Sizin durumunuzda, yalnızca FloorPlanSettings nesnesini istiyorsanız, Encodeşu özelliğin yöntemini iletmeniz yeterlidir :

var floorplanSettings = @Html.Raw(Json.Encode(Model.FloorPlanSettings));

1
Sadece onaylamak için bir eklemeye gerek yoktur; sonunda? Ben VS bildirimi sonlandırılmadığını belirten bir istem almak çünkü. Ama eklemeye çalıştığımda; kod çalışmaz
Null Reference

1
Ne biliyorsun, çeşitli projelerimde de aynı hatayı aldım. Görmezden gel; Visual Studio yardım etmeye çalışıyor, ancak bu durumda yanlış. Tarayıcıya gönderilen sonuç HTML ve komut dosyası doğrudur.
Justin Helgerson

1
Benim için bu çalıştı: var myModel = @ {@ Html.Raw (Json.Encode (Model));}
gizli

1
Model başlangıç ​​değeri ise (Düzenle sayfası yerine sayfa oluştur) ve "ReferenceError: Model tanımlanmadı" durumunda çalışmaz.
Jack,

2
ASP.Net Core, Json.Serialize ()
Mohammed Noureldin

131

Yanıtın İçeriği

1) .cshtmlDosyadaki Javascript / Jquery kod bloğundaki Model verilerine nasıl erişilir

2) .jsDosyadaki Javascript / Jquery kod bloğundaki Model verilerine nasıl erişilir

.cshtmlDosyadaki Javascript / Jquery kod bloğundaki Model verilerine nasıl erişilir

ModelJavaScript değişkenine iki tür c # değişken ( ) ataması vardır.

  1. Mülkiyet atama - Temel veri türleri gibi int, string, DateTime(örn: Model.Name)
  2. Nesne atama - Özel veya dahili sınıfları (örn: Model, Model.UserSettingsObj)

Bu iki ödevin ayrıntılarına bakalım.

Cevabın geri kalanı için aşağıdaki AppUserModeli örnek olarak ele alalım.

public class AppUser
{
    public string Name { get; set; }
    public bool IsAuthenticated { get; set; }
    public DateTime LoginDateTime { get; set; }
    public int Age { get; set; }
    public string UserIconHTML { get; set; }
}

Ve bu Modeli atadığımız değerler

AppUser appUser = new AppUser
{
    Name = "Raj",
    IsAuthenticated = true,
    LoginDateTime = DateTime.Now,
    Age = 26,
    UserIconHTML = "<i class='fa fa-users'></i>"
};

Mülk ataması

Ödev için farklı sözdizimi kullanalım ve sonuçları gözlemleyelim.

1) Özellik atamasını tırnak içine almadan.

var Name = @Model.Name;  
var Age = @Model.Age;
var LoginTime = @Model.LoginDateTime; 
var IsAuthenticated = @Model.IsAuthenticated;   
var IconHtml = @Model.UserIconHTML;  

resim açıklamasını buraya girin

Gördüğünüz gibi birkaç hata var Rajve Truejavascript değişkenleri olarak kabul ediliyor ve var olmadığı için bu bir variable undefinedhata. DateTime değişkenine gelince hatanın unexpected numbersayıları özel karakterlere sahip olamazsa, HTML etiketleri varlık adlarına dönüştürülür, böylece tarayıcı değerlerinizi ve HTML işaretlemesini karıştırmaz.

2) Tırnak içinde özellik atama.

var Name = '@Model.Name';
var Age = '@Model.Age';
var LoginTime = '@Model.LoginDateTime';
var IsAuthenticated = '@Model.IsAuthenticated';
var IconHtml = '@Model.UserIconHTML'; 

resim açıklamasını buraya girin

Sonuçlar geçerlidir, Bu nedenle özellik atamasını tırnak içine almak bize geçerli bir sözdizimi verir. Ama numara Ageşimdi bir dize olduğunu unutmayın , Yani istemiyorsanız sadece tırnak kaldırabilirsiniz ve bir sayı türü olarak işlenir.

3) kullanarak @Html.Rawancak olmadan tırnak içinde sararak

 var Name = @Html.Raw(Model.Name);
 var Age = @Html.Raw(Model.Age);
 var LoginTime = @Html.Raw(Model.LoginDateTime);
 var IsAuthenticated = @Html.Raw(Model.IsAuthenticated);
 var IconHtml = @Html.Raw(Model.UserIconHTML);

resim açıklamasını buraya girin

Sonuçlar Ancak kullanarak test durumu 1. benzer @Html.Raw()üzerinde HTMLbize bazı değişiklik gösterdi mi dize. HTML, varlık adlarına değiştirilmeden korunur.

Html.Raw () dokümanlarından

HTML işaretlemesini HTML işaretlemesi olarak yorumlanacak şekilde bir HtmlString örneğinde sarar.

Ama yine de diğer satırlarda hatalarımız var.

4) kullanma @Html.Rawve tırnak içine sarma

var Name ='@Html.Raw(Model.Name)';
var Age = '@Html.Raw(Model.Age)';
var LoginTime = '@Html.Raw(Model.LoginDateTime)';
var IsAuthenticated = '@Html.Raw(Model.IsAuthenticated)';
var IconHtml = '@Html.Raw(Model.UserIconHTML)';

resim açıklamasını buraya girin

Sonuçlar tüm tiplerde iyidir. Ancak HTMLverilerimiz artık kırıldı ve bu komut dosyalarını bozacak. Sorun, 'verileri sarmak için tek tırnak kullandığımız ve hatta verilerin tek tırnak içerdiği için.

Bu sorunu 2 yaklaşımla aşabiliriz.

1) " "HTML bölümünü sarmak için çift ​​tırnak kullanın. Iç veriler sadece tek tırnak olduğu için. (Çift tırnak işareti ile kaydırdıktan "sonra verilerin içinde de bulunmadığından emin olun )

  var IconHtml = "@Html.Raw(Model.UserIconHTML)";

2) Sunucu tarafı kodunuzdaki karakter anlamından kaçın. Sevmek

  UserIconHTML = "<i class=\"fa fa-users\"></i>"

Mülkiyet tahsisinin sonuçlandırılması

  • Sayısal olmayan dataType için tırnak işaretleri kullanın.
  • Sayısal dataType için tırnak işareti kullanmayın.
  • Html.RawHTML verilerinizi olduğu gibi yorumlamak için kullanın .
  • Sunucu verilerindeki tırnak anlamından kaçmak için HTML verilerinize dikkat edin veya javascript değişkenine atama sırasında verilerden farklı bir alıntı kullanın.

Nesne atama

Ödev için farklı sözdizimi kullanalım ve sonuçları gözlemleyelim.

1) Nesne atamasını tırnak içine almadan.

  var userObj = @Model; 

resim açıklamasını buraya girin

Javascript değişkenine ac # nesnesi atadığınızda .ToString(), o atlamanın değeri atanacaktır. Dolayısıyla yukarıdaki sonuç.

2 Alıntılarda nesne kaydırma

var userObj = '@Model'; 

resim açıklamasını buraya girin

3)Html.Raw Tırnaklar olmadan kullanma .

   var userObj = @Html.Raw(Model); 

resim açıklamasını buraya girin

4)Html.Raw Tırnaklarla birlikte kullanma

   var userObj = '@Html.Raw(Model)'; 

resim açıklamasını buraya girin

Html.RawDeğişkene bir nesne atarken bizim için çok faydası oldu.

5)Json.Encode() Tırnaklar olmadan kullanma

var userObj = @Json.Encode(Model); 

//result is like
var userObj = {&quot;Name&quot;:&quot;Raj&quot;,
               &quot;IsAuthenticated&quot;:true,
               &quot;LoginDateTime&quot;:&quot;\/Date(1482572875150)\/&quot;,
               &quot;Age&quot;:26,
               &quot;UserIconHTML&quot;:&quot;\u003ci class=\&quot;fa fa-users\&quot;\u003e\u003c/i\u003e&quot;
              };

Bazı değişiklikler görüyoruz, Modelimizin bir nesne olarak yorumlandığını görüyoruz. Ama o özel karakterlere dönüştük entity names. Yukarıdaki sözdizimini tırnak içine almak da pek işe yaramaz. Aynı sonucu tırnak içinde alırız.

Json.Encode () dokümanlarından

Bir veri nesnesini JavaScript Nesne Gösterimi (JSON) biçimindeki bir dizeye dönüştürür.

entity NameMülk atamasıyla bu sorunla daha önce karşılaştığınız ve hatırlarsanız, kullanımı ile üstesinden geldik Html.Raw. Hadi deneyelim. Birleştirelim Html.RawveJson.Encode

6) Tırnaklı Html.Rawve Json.Encodetırnaksız.

var userObj = @Html.Raw(Json.Encode(Model));

Sonuç geçerli bir Javascript Nesnesidir

 var userObj = {"Name":"Raj",
     "IsAuthenticated":true,
     "LoginDateTime":"\/Date(1482573224421)\/",
     "Age":26,
     "UserIconHTML":"\u003ci class=\"fa fa-users\"\u003e\u003c/i\u003e"
 };

resim açıklamasını buraya girin

7) kullanılması Html.Rawve Json.Encodetırnak içinde.

var userObj = '@Html.Raw(Json.Encode(Model))';

resim açıklamasını buraya girin

Tırnaklarla kaydırmayı gördüğünüz gibi bize bir JSON verisi verir

Nesne atamasına ilişkin sonuç

  • Nesnenizi javascript değişkenine JavaScript nesnesi olarak atamak için Html.Rawve Json.Encodebirleşiminde kullanın .
  • Bir JSON almak için kullanın Html.Rawve Json.Encodeiçine sarınquotes

Not: DataTime veri formatının doğru olmadığını gözlemlediyseniz. Bunun nedeni, daha önce de belirtildiği gibi Converts a data object to a string that is in the JavaScript Object Notation (JSON) formatve JSON bir datetür içermemesidir . Bunu düzeltmenin diğer seçenekleri, javascipt Date () nesnesini kullanarak bu türü tek başına işlemek için başka bir kod satırı eklemektir.

var userObj.LoginDateTime = new Date('@Html.Raw(Model.LoginDateTime)'); 
//without Json.Encode


.jsDosyadaki Javascript / Jquery kod bloğundaki Model verilerine nasıl erişilir

Razor sözdiziminin .jsdosyada bir anlamı yoktur ve bu nedenle Modelimizi doğrudan bir .jsdosyaya ekleyemeyiz . Ancak bir çözüm var.

1) Çözüm javascript Global değişkenlerini kullanmaktır .

Değeri genel kapsamdaki bir javascipt değişkenine atamalı ve sonra bu değişkeni sizin .cshtmlve .jsdosyalarınızın tüm kod bloğu içinde kullanmalıyız . Yani sözdizimi

<script type="text/javascript">
  var userObj = @Html.Raw(Json.Encode(Model)); //For javascript object
  var userJsonObj = '@Html.Raw(Json.Encode(Model))'; //For json data
</script>

Bu ile değişkenleri userObjve userJsonObjgerektiğinde ve gerektiği zaman kullanabiliriz .

Not: Ben şahsen, küresel değişkenlerin bakım için zorlaşmasını önermiyorum. Ancak başka bir seçeneğiniz yoksa, uygun bir adlandırma kuralına sahip olarak kullanabilirsiniz .. gibi bir şey userAppDetails_global.

2) Bir işlevdekiclosure model verilerine bağlı olan tüm kodu function () veya Wrap kullanarak . Ve sonra bu işlevi .cshtmldosyadan yürütün .

external.js

 function userDataDependent(userObj){
  //.... related code
 }

.cshtml dosya

 <script type="text/javascript">
  userDataDependent(@Html.Raw(Json.Encode(Model))); //execute the function     
</script>

Not: Harici komut dosyasına yukarıdaki komut dosyasından önce başvurulmalıdır. Aksi takdirde userDataDependentişlev tanımsızdır.

Ayrıca işlevin de global kapsamda olması gerektiğini unutmayın. Yani her iki çözüm de küresel kapsamdaki oyuncularla uğraşmak zorundayız.


Model özelliği javascript ile güncellenebilir ve kontrolör eylem yöntemine gönderilebilir mi?

@sortednoun evet yapabilirsiniz, Bir formdan değiştirilmiş verileri geri gönderebilirsiniz veya Sayfayı yeniden yüklemek istemiyorsanız, AJAX
Rajshekar Reddy

Ajax kullanmıyordum ve sadece javascript model özelliğini değiştirmeye çalıştım. ancak form gönderildiğinde bu değişiklik modele yansıtılmamıştır. Gibi bir şey yapıyordum: var model = @ Html.Raw (Json.Encode (Model)); model.EventCommand = "güncellenmiş değer"; Bana model doğru ve güncellenmiş değer verdi, ancak gönderildiğinde değişiklik eylem yönteminde eksikti. (Her ne kadar ben gizli Html kontrolü kullanarak aynı şeyi yaptım ve EventCommand bağlı ve javascript değerini güncelledi rağmen. Ama aynı model doğrudan yapmak için merak?)

@sortednoun Demek istediğim, var model = @Html.Raw(Json.Encode(Model));bu, görünüme ilettiğiniz C # Modeli ile bağlantısı olmayan bir javascript nesnesi model oluşturur. Etki Model, görünüm oluşturulduktan sonra hayır olmayacaktır . Dolayısıyla, kullanıcı arayüzündeki Form'un javascript nesnesi veri değişiklikleri hakkında hiçbir fikri olmayacaktır. Şimdi bu modifiye edilmiş modelin tamamını AJAX üzerinden denetleyiciye geçirmeniz veya Ya da giriş denetimlerinizin değerini javascript kullanarak formda güncellemeniz gerekir.
Rajshekar Reddy

Although I did the same thing using hidden Html control and bound it to EventCommand and updated it's value in javascript. But wondering if could do same directly to model?Bu ifade için .. EventCommand MVC hiçbir , UI ve sunucu eylemleri arasında bir bağlantı olduğu Webforms için, MVC tüm ayrılmış. Denetleyiciyle etkileşim kurmanın tek yolu AJAX veya Form Gönder veya Yeni sayfa İsteği (yeniden yükleme de)
Rajshekar Reddy

21

Şunu deneyin: (tek tırnakları kaçırdınız)

var floorplanSettings = '@Html.Raw(Json.Encode(Model.FloorPlanSettings))';

1
@JuanPieterse tırnak ile size bir JSONwihtout tırnak verir bir javascript Object. Daha fazla ayrıntı için aynı ileti dizisindeki cevabımı kontrol edin. stackoverflow.com/a/41312348/2592042
Rajshekar Reddy

Bu doğru değil, @danmbuen çözümü benim durumumda çalıştı, sorunlarım var ve tek tırnaklar arasında bir çekicilik gibi çalıştı, TEŞEKKÜR EDERİZ;)
Dimitri

4

Model mülkü parenslerin etrafına sarmak benim için çalıştı. Aynı sorunu Visual Studio ile noktalı virgül hakkında şikayet ediyorsun, ama işe yarıyor.

var closedStatusId = @(Model.ClosedStatusId);

0

"ReferenceError: Model tanımlanmadı" hatası ortaya çıkarsa , aşağıdaki yöntemi kullanmayı deneyebilirsiniz:

$(document).ready(function () {

    @{  var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
         var json = serializer.Serialize(Model);
    }

    var model = @Html.Raw(json);
    if(model != null && @Html.Raw(json) != "undefined")
    {
        var id= model.Id;
        var mainFloorPlanId = model.MainFloorPlanId ;
        var imageDirectory = model.ImageDirectory ;
        var iconsDirectory = model.IconsDirectory ;
    }
});

Bu yardımcı olur umarım...


0

Çok geç olduğunu biliyorum ama bu çözüm hem .net çerçevesi hem de .net çekirdeği için mükemmel çalışıyor:

@ System.Web.HttpUtility.JavaScriptStringEncode ()

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.