Доступ до властивості моделі MVC з Javascript


147

У мене є така модель, яка вкладена в мою модель перегляду

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?

Я спробував це, але я отримав "невизначений"

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

5
Для того, щоб зрозуміти, що відбувається - ви встановлюєте значення змінної JavaScript на значення змінної C # "Model.FloorPlanSettings", яка буде значенням .ToString () цього класу (рядок). Потім ви намагаєтеся попередити властивість JavaScript під назвою "IconsDirectory" на щойно створеній вами змінній рядка JavaScript. Ви не визначаєтесь, оскільки рядок JavaScript не має властивості "IconsDirectory".
Джоель Кокран

Надав повний тестовий випадок та пояснив усі сценарії призначення даних Моделі до змінної javascript,
Rajshekar Reddy

Це не працює поза вікном перегляду (cshtml). тобто у зовнішньому .js-файлі, на який посилається представлення.
Спенсер Салліван

Відповіді:


240

Ви можете взяти всю модель на стороні сервера і перетворити її в об'єкт Javascript, виконавши наступні дії:

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

У вашому випадку, якщо ви просто хочете об'єкт FloorPlanSettings, просто передайте Encodeметод, який властиво:

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

1
Тільки для підтвердження, додавати не потрібно; в кінці цього? Тому що я отримую від VS підказку про те, що заява не припиняється. Але коли я намагаюся додати; код не працює
Null Reference

1
Що ти знаєш, у моїх різних проектах є однакові помилки. Просто ігноруйте це; це Visual Studio намагається допомогти, але в цьому випадку це неправильно. Отриманий HTML та скрипт, який надсилається до браузера, є правильним.
Джастін Гельгерсон

1
Для мене це спрацювало: var myModel = @ {@ Html.Raw (Json.Encode (Model));}
приховано

1
Не працює, якщо модель є початковим значенням (Створити сторінку замість Редагувати сторінку) та виникає "ReferenceError: Модель не визначено".
Джек

2
В ASP.Net Core, Json.Serialize ()
Мохаммед Нурелдін

131

Зміст відповіді

1) Як отримати доступ до даних моделі у блоці коду Javascript / Jquery у .cshtmlфайлі

2) Як отримати доступ до даних моделі у блоці коду Javascript / Jquery у .jsфайлі

Як отримати доступ до даних моделі у блоці коду Javascript / Jquery у .cshtmlфайлі

Існує два типи Modelприсвоєння змінної JavaScript # (c ).

  1. Призначення нерухомості - Основні типи даних подобається int, string, DateTime(наприклад: Model.Name)
  2. Призначення об'єкта - для користувача або вбудовані класи (наприклад: Model, Model.UserSettingsObj)

Давайте розглянемо деталі цих двох завдань.

Для решти відповіді давайте розглянемо наведену нижче AppUserмодель як приклад.

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; }
}

І значення, які ми присвоюємо цій Моделі, є

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

Призначення власності

Дозволяє використовувати різні синтаксиси для призначення та спостерігати за результатами.

1) Без загортання призначення власності в лапки.

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

введіть тут опис зображення

Як ви бачите, є кілька помилок, Rajі Trueце вважається змінними javascript, а оскільки вони не існують, є його variable undefinedпомилкою. Якщо щодо змінної dateTime помилка полягає в тому, що unexpected numberцифри не можуть мати спеціальних символів, теги HTML перетворюються у назви сутностей, щоб браузер не змішував ваші значення та розмітку HTML.

2) Обгортка призначення властивостей у котируваннях.

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

введіть тут опис зображення

Результати справедливі, тому загортання призначення властивостей у лапки дає нам дійсний синтаксис. Але зауважте, що число Ageтепер є рядком, тому, якщо ви не хочете, ми можемо просто видалити лапки, і він буде відображатися як тип номера.

3) Використання, @Html.Rawале не загортаючи його в лапки

 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);

введіть тут опис зображення

Результати аналогічні наш тест 1. Однак при використанні @Html.Raw()на HTMLрядку були показати нам деякі зміни. HTML зберігається, не змінюючи назви своїх об'єктів.

Від документів Html.Raw ()

Обгортає розмітку HTML в екземплярі HtmlString, щоб вона інтерпретувалася як розмітка HTML.

Але все ж ми маємо помилки в інших рядках.

4) Використання, @Html.Rawа також загортання його в лапки

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)';

введіть тут опис зображення

Результати хороші при всіх типах. Але наші HTMLдані зараз порушені, і це порушить сценарії. Проблема полягає в тому, що ми використовуємо одинарні лапки, 'щоб обернути дані, і навіть дані мають єдині лапки.

Ми можемо подолати це питання за допомогою двох підходів.

1) використовуйте подвійні лапки, " "щоб обернути частину HTML. Оскільки внутрішні дані мають лише одиничні лапки. (Будьте впевнені, що після обгортання з подвійними лапками "в даних також немає

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

2) Уникнути значення символу в коді сторони вашого сервера. Подібно до

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

Висновок присвоєння майна

  • Використовуйте лапки для нечислових данихType.
  • Не використовуйте лапки для числового типу даних.
  • Використовуйте Html.Rawдля інтерпретації ваших HTML-даних як є.
  • Подбайте про свої HTML-дані, щоб уникнути значення цитат на стороні сервера, або використовуйте іншу цитату, ніж у даних під час присвоєння змінній javascript.

Призначення об'єкта

Дозволяє використовувати різні синтаксиси для призначення та спостерігати за результатами.

1) Без загортання призначення об'єктів у лапки.

  var userObj = @Model; 

введіть тут опис зображення

Якщо ви призначите об'єкт ac # перемінному javascript .ToString(), то буде вказано значення цього oject. Звідси вищенаведений результат.

2 Загортання призначення об'єктів у лапки

var userObj = '@Model'; 

введіть тут опис зображення

3) Використання Html.Rawбез лапок.

   var userObj = @Html.Raw(Model); 

введіть тут опис зображення

4) Використання Html.Rawразом із цитатами

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

введіть тут опис зображення

Для нас Html.Rawце не мало користі при призначенні об'єкта змінній.

5) Використання Json.Encode()без лапок

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;
              };

Ми бачимо певні зміни, ми бачимо, що наша модель трактується як об'єкт. Але в нас змінилися ці особливі персонажі entity names. Також обгортання вищезгаданого синтаксису в лапки не приносить користі. Ми просто отримуємо той самий результат у котируваннях.

З документів Json.Encode ()

Перетворює об'єкт даних у рядок, що знаходиться у форматі JavaScript Object Notation (JSON).

Як ви вже стикалися з цією entity Nameпроблемою з присвоєнням власності, і якщо ви пам’ятаєте, ми подолали її з використанням Html.Raw. Тож давайте спробуємо це. Давайте комбінувати Html.RawіJson.Encode

6) Використання Html.Rawі Json.Encodeбез лапок.

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

Результат - дійсний об'єкт Javascript

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

введіть тут опис зображення

7) Використання Html.Rawі Json.Encodeв межах лапок.

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

введіть тут опис зображення

Як ви бачите, обгортання цитатами дає нам дані JSON

Висновок щодо присвоєння об'єкта

  • Використовуйте Html.Rawта Json.Encodeв поєднанні, щоб призначити ваш об'єкт змінній javascript як об’єкт JavaScript .
  • Використовуйте, Html.Rawа Json.Encodeтакож оберніть його всередині, quotesщоб отримати JSON

Примітка. Якщо ви помітили, що формат даних DataTime неправильний. Це тому, що, як було сказано раніше, Converts a data object to a string that is in the JavaScript Object Notation (JSON) formatJSON не містить dateтипу. Інші варіанти , щоб виправити це , щоб додати ще один рядок коду для обробки цього типу в поодинці , використовуючи Javascipt Дата) ( об'єкт

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


Як отримати доступ до даних моделі у блоці коду Javascript / Jquery у .jsфайлі

Синтаксис Razor не має жодного значення у .jsфайлі, і тому ми не можемо безпосередньо використовувати модель Model insisde .jsфайл. Однак є рішення.

1) Рішення використовує глобальні змінні javascript .

Ми повинні призначити значення глобальній змінній javascipt змінної, а потім використовувати цю змінну у всьому кодовому блоці ваших .cshtmlта .jsфайлів. Отже, синтаксис був би

<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>

Маючи це на місці, ми можемо використовувати змінні userObjта userJsonObjяк і коли це потрібно.

Примітка. Я особисто не пропоную використовувати глобальні змінні, оскільки це стає дуже важким для обслуговування. Однак якщо у вас немає іншого варіанту, ви можете використовувати його, якщо мати правильну конвенцію про іменування .. щось подібне userAppDetails_global.

2) Використовуючи функцію () або closure Обернути весь код, який залежить від даних моделі у функції. А потім виконати цю функцію з .cshtmlфайлу.

external.js

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

.cshtml файл

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

Примітка: Ваш зовнішній файл повинен бути посилається на попередній сценарій. В іншому випадку userDataDependentфункція не визначена.

Також зауважте, що функція повинна бути і в глобальному масштабі. Таким чином, будь-яким рішенням ми маємо мати справу з глобальними гравцями, які охоплюють область.


Чи можна оновити властивість Model у JavaScript та надіслати метод дії контролера?

@sortednoun так, ви можете, ви можете надіслати змінені дані із форми, або якщо ви не хочете перезавантажувати сторінку, тоді ви можете скористатися AJAX
Rajshekar Reddy

Я не використовував ajax, а просто намагався змінити властивість моделі в JavaScript. але після подання форми ця зміна не відображена в моделі. Я робив щось на кшталт: var model = @ Html.Raw (Json.Encode (Model)); model.EventCommand = "оновлено значення"; Це дало мені правильну модель та оновило значення, але після подання зміна відсутня у методі дій. (Хоча я робив те ж саме, використовуючи прихований контроль Html і прив’язував його до EventCommand та оновив його значення в JavaScript. Але цікаво, чи можна було б зробити те саме безпосередньо для моделі?)

@sortednoun Я зрозумів, що var model = @Html.Raw(Json.Encode(Model));це створить об'єкт javascript, model який не має зв'язку з моделлю C #, яку ви переходите до подання. Інфакта не буде, Modelпісля того, як вид буде надано. Таким чином, Форма в інтерфейсі не матиме поняття про зміни даних об’єкта javascript. Тепер вам потрібно передати всю цю модифіковану модель контролеру через AJAX, або вам потрібно оновити значення вхідних елементів керування у формі за допомогою javascript.
Раджешекар Редді

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?для цього твердження .. EventCommand у MVC немає , його для Webforms, де існує зв'язок між інтерфейсом користувача та діями сервера, у MVC його все розділено. Єдиний спосіб взаємодії з контролером - це через AJAX або Надіслати форму або Запросити нову сторінку (також перезавантажте)
Rajshekar Reddy

21

спробуйте це: (ви пропустили єдині цитати)

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

1
@JuanPieterse з цитатами дає вам JSONбез котирувань дає вам javascript Object. Перевірте мою відповідь у тій самій нитці, щоб отримати детальнішу інформацію. stackoverflow.com/a/41312348/2592042
Rajshekar Reddy

Це неправда, рішення @danmbuen працювало в моєму випадку, у мене виникли проблеми, і загортання його між окремими цитатами працювало як принадність, ДЯКУЮ;)
Димитрій

4

Обертання властивості моделі навколо паронів працювало на мене. Ви все ще отримуєте те саме питання, що Visual Studio скаржиться на напівкрапку, але це працює.

var closedStatusId = @(Model.ClosedStatusId);

0

Якщо помилка "ReferenceError: Model не визначена" порушена, ви можете спробувати скористатися наступним методом:

$(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 ;
    }
});

Сподіваюся, це допомагає ...


0

Я знаю, що це занадто пізно, але це рішення працює ідеально як для .net Framework, так і для .net core:

@ System.Web.HttpUtility.JavaScriptStringEncode ()

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.