Truy cập thuộc tính mô hình của MVC từ Javascript


147

Tôi có mô hình sau đây được bao bọc trong mô hình xem của tôi

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

Làm cách nào để truy cập một trong các thuộc tính trên từ Javascript?

Tôi đã thử điều này, nhưng tôi đã "không xác định"

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

5
Để rõ ràng, điều đang xảy ra là bạn đang đặt giá trị của biến JavaScript thành giá trị của biến C # "Model.FloorPlanSinstall", sẽ là giá trị .ToString () của lớp đó (một chuỗi). Sau đó, bạn đang cố gắng cảnh báo một thuộc tính JavaScript có tên là "IconDirectory" trên biến chuỗi JavaScript bạn vừa tạo. Bạn nhận được không xác định vì một chuỗi JavaScript không có thuộc tính "IconDirectory".
Joel Cochran

Đã cung cấp một trường hợp thử nghiệm hoàn chỉnh và giải thích tất cả các kịch bản gán dữ liệu Mô hình cho biến javascript,
Rajshekar Reddy

Điều này không hoạt động bên ngoài chế độ xem (cshtml). tức là trong tệp .js bên ngoài được tham chiếu bởi khung nhìn.
Spencer Sullivan

Câu trả lời:


240

Bạn có thể lấy toàn bộ mô hình phía máy chủ của mình và biến nó thành một đối tượng Javascript bằng cách thực hiện như sau:

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

Trong trường hợp của bạn nếu bạn chỉ muốn đối tượng FloorPlanSinstall, chỉ cần truyền Encodephương thức thuộc tính đó:

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

1
Chỉ cần xác nhận, không cần thêm a; vào cuối của nó? Bởi vì tôi nhận được một lời nhắc từ VS nói rằng tuyên bố không bị chấm dứt. Nhưng khi tôi cố gắng thêm; mã không chạy
Tham chiếu Null

1
Bạn biết gì không, tôi cũng có lỗi tương tự trong các dự án khác nhau của mình. Chỉ cần bỏ qua nó; đó là Visual Studio đang cố gắng giúp đỡ, nhưng, nó đã sai trong trường hợp này. Kết quả HTML và tập lệnh được gửi tới trình duyệt là chính xác.
Justin Helgerson

1
Đối với tôi, điều này đã hoạt động: var myModel = @ {@ Html.Raw (Json.Encode (Model));}
ẩn

1
Không hoạt động nếu mô hình là giá trị ban đầu (Tạo trang thay vì trang Chỉnh sửa) và gặp phải "ReferenceError: Model không được xác định".
Jack

2
Trong Lõi ASP.Net, Json.Serialize ()
Mohammed Noureldin

131

Nội dung câu trả lời

1) Cách truy cập dữ liệu Mô hình trong khối mã Javascript / Jquery trong .cshtmltệp

2) Cách truy cập dữ liệu Mô hình trong khối mã Javascript / Jquery trong .jstệp

Cách truy cập dữ liệu Mô hình trong khối mã Javascript / Jquery trong .cshtmltệp

Có hai loại Modelphép gán biến c # ( ) cho biến JavaScript.

  1. Chuyển nhượng bất động sản - kiểu dữ liệu cơ bản như int, string, DateTime(ví dụ: Model.Name)
  2. Phân công đối tượng - Tuỳ chỉnh hoặc lớp sẵn có (ví dụ: Model, Model.UserSettingsObj)

Hãy nhìn vào chi tiết của hai bài tập này.

Đối với phần còn lại của câu trả lời, hãy xem xét AppUserMô hình dưới đây làm ví dụ.

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

Và các giá trị chúng ta gán cho Mô hình này là

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

Chuyển nhượng tài sản

Cho phép sử dụng cú pháp khác nhau để gán và quan sát kết quả.

1) Không có sự phân công tài sản trong dấu ngoặc kép.

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

nhập mô tả hình ảnh ở đây

Như bạn có thể thấy có một vài lỗi RajTrueđược coi là các biến javascript và vì chúng không tồn tại variable undefinedlỗi. Trong trường hợp đối với biến đổi dateTime, lỗi là các unexpected numbersố không thể có các ký tự đặc biệt, các thẻ HTML được chuyển đổi thành tên thực thể để trình duyệt không trộn lẫn các giá trị của bạn và đánh dấu HTML.

2) Đóng gói chuyển nhượng tài sản trong Báo giá.

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

nhập mô tả hình ảnh ở đây

Các kết quả là hợp lệ, do đó, việc gán thuộc tính trong dấu ngoặc kép cho chúng ta cú pháp hợp lệ. Nhưng lưu ý rằng Số Agebây giờ là một chuỗi, vì vậy nếu bạn không muốn rằng chúng ta có thể xóa các trích dẫn và nó sẽ được hiển thị dưới dạng một loại số.

3) Sử dụng @Html.Rawnhưng không gói nó trong dấu ngoặc kép

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

nhập mô tả hình ảnh ở đây

Kết quả tương tự như trường hợp thử nghiệm của chúng tôi 1. Tuy nhiên, việc sử dụng @Html.Raw()trên HTMLchuỗi đã cho chúng tôi thấy một số thay đổi. HTML được giữ lại mà không thay đổi tên thực thể của nó.

Từ tài liệu Html.Raw ()

Kết thúc đánh dấu HTML trong một phiên bản HtmlString để nó được hiểu là đánh dấu HTML.

Nhưng chúng tôi vẫn có lỗi trong các dòng khác.

4) Sử dụng @Html.Rawvà cũng gói nó trong dấu ngoặc kép

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

nhập mô tả hình ảnh ở đây

Kết quả tốt với tất cả các loại. Nhưng HTMLdữ liệu của chúng tôi hiện đã bị hỏng và điều này sẽ phá vỡ các tập lệnh. Vấn đề là bởi vì chúng tôi đang sử dụng dấu ngoặc đơn 'để bọc dữ liệu và thậm chí dữ liệu có dấu ngoặc đơn.

Chúng tôi có thể khắc phục vấn đề này với 2 cách tiếp cận.

1) sử dụng dấu ngoặc kép " "để bọc phần HTML. Vì dữ liệu bên trong chỉ có dấu ngoặc đơn. (Hãy chắc chắn rằng sau khi gói bằng dấu ngoặc kép cũng không có "trong dữ liệu)

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

2) Thoát khỏi ý nghĩa ký tự trong mã phía máy chủ của bạn. Giống

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

Kết luận chuyển nhượng tài sản

  • Sử dụng dấu ngoặc kép cho kiểu dữ liệu không phải là số.
  • Không sử dụng dấu ngoặc kép cho kiểu dữ liệu số.
  • Sử dụng Html.Rawđể giải thích dữ liệu HTML của bạn.
  • Chăm sóc dữ liệu HTML của bạn để thoát khỏi dấu ngoặc kép ở phía máy chủ, hoặc sử dụng một trích dẫn khác với dữ liệu trong khi gán cho biến javascript.

Phân công đối tượng

Cho phép sử dụng cú pháp khác nhau để gán và quan sát kết quả.

1) Không có sự phân công đối tượng trong dấu ngoặc kép.

  var userObj = @Model; 

nhập mô tả hình ảnh ở đây

Khi bạn gán đối tượng ac # cho biến javascript, giá trị của .ToString()từ đó sẽ được chỉ định. Do đó kết quả trên.

2 Đóng gói đối tượng trong dấu ngoặc kép

var userObj = '@Model'; 

nhập mô tả hình ảnh ở đây

3) Sử dụng Html.Rawmà không có dấu ngoặc kép.

   var userObj = @Html.Raw(Model); 

nhập mô tả hình ảnh ở đây

4) Sử dụng Html.Rawcùng với dấu ngoặc kép

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

nhập mô tả hình ảnh ở đây

Chúng tôi Html.Rawkhông sử dụng nhiều trong khi gán một đối tượng cho biến.

5) Sử dụng Json.Encode()mà không có dấu ngoặc kép

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

Chúng tôi thấy một số thay đổi, Chúng tôi thấy Mô hình của chúng tôi đang được hiểu là một đối tượng. Nhưng chúng ta có những nhân vật đặc biệt được thay đổi thành entity names. Ngoài ra gói cú pháp trên trong dấu ngoặc kép là không sử dụng nhiều. Chúng tôi chỉ đơn giản nhận được kết quả tương tự trong dấu ngoặc kép.

Từ các tài liệu của Json.Encode ()

Chuyển đổi một đối tượng dữ liệu thành một chuỗi ở định dạng Ký hiệu đối tượng JavaScript (JSON).

Vì bạn đã gặp phải entity Namevấn đề này với việc chuyển nhượng tài sản và nếu bạn nhớ chúng tôi đã khắc phục nó bằng việc sử dụng Html.Raw. Vì vậy, hãy thử nó. Hãy kết hợp Html.RawJson.Encode

6) Sử dụng Html.RawJson.Encodekhông có dấu ngoặc kép.

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

Kết quả là một đối tượng Javascript hợp lệ

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

nhập mô tả hình ảnh ở đây

7) Sử dụng Html.RawJson.Encodetrong dấu ngoặc kép.

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

nhập mô tả hình ảnh ở đây

Như bạn thấy gói bằng dấu ngoặc kép cung cấp cho chúng tôi dữ liệu JSON

Kết luận về phân công đối tượng

  • Sử dụng Html.RawJson.Encodekết hợp để gán đối tượng của bạn cho biến javascript làm đối tượng JavaScript .
  • Sử dụng Html.RawJson.Encodecũng bọc nó bên trong quotesđể lấy JSON

Lưu ý: Nếu bạn đã quan sát định dạng dữ liệu DataTime là không đúng. Điều này là do như đã nói trước đó Converts a data object to a string that is in the JavaScript Object Notation (JSON) formatvà JSON không chứa một dateloại. Các tùy chọn khác để khắc phục điều này là thêm một dòng mã khác để xử lý loại này một mình bằng cách sử dụng đối tượng javascipt Date ()

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


Cách truy cập dữ liệu Mô hình trong khối mã Javascript / Jquery trong .jstệp

Cú pháp dao động không có ý nghĩa trong .jstệp và do đó chúng tôi không thể trực tiếp sử dụng Mô hình của mình trong khi tạo .jstệp. Tuy nhiên, có một cách giải quyết.

1) Giải pháp đang sử dụng các biến toàn cầu javascript .

Chúng ta phải gán giá trị cho biến javascipt phạm vi toàn cầu và sau đó sử dụng biến này trong tất cả các khối mã của bạn .cshtml.jscác tệp. Vì vậy, cú pháp sẽ là

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

Với điều này trong nơi chúng ta có thể sử dụng các biến userObjuserJsonObjnhư và khi cần thiết.

Lưu ý: Cá nhân tôi không đề xuất sử dụng các biến toàn cục vì nó rất khó bảo trì. Tuy nhiên nếu bạn không có lựa chọn nào khác thì bạn có thể sử dụng nó với một quy ước đặt tên thích hợp .. đại loại như thế userAppDetails_global.

2) Sử dụng hàm () hoặc closure Bọc tất cả mã phụ thuộc vào dữ liệu mô hình trong một hàm. Và sau đó thực hiện chức năng này từ .cshtmltập tin.

external.js

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

.cshtml tập tin

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

Lưu ý: Tệp bên ngoài của bạn phải được tham chiếu trước tập lệnh trên. Khác userDataDependentchức năng là không xác định.

Cũng lưu ý rằng chức năng phải nằm trong phạm vi toàn cầu. Vì vậy, một trong hai giải pháp chúng ta phải đối phó với những người chơi có phạm vi toàn cầu.


Thuộc tính Model có thể được cập nhật trong javascript và gửi đến phương thức hành động của bộ điều khiển không?

@sortnoun có, bạn có thể, Bạn có thể gửi lại dữ liệu đã sửa đổi từ một biểu mẫu, hoặc nếu bạn không muốn tải lại trang thì bạn có thể sử dụng AJAX
Rajshekar Reddy

Tôi đã không sử dụng ajax và chỉ cố gắng sửa đổi thuộc tính mô hình trong javascript. nhưng khi nộp mẫu đơn, sự thay đổi này không được phản ánh trong mô hình. Tôi đã làm một cái gì đó như: var model = @ Html.Raw (Json.Encode (Model)); model.EventCommand = "updatevalue"; Nó đã cho tôi mô hình chính xác và giá trị cập nhật, nhưng khi gửi thay đổi bị thiếu trong phương thức hành động. (Mặc dù tôi đã làm điều tương tự bằng cách sử dụng điều khiển Html ẩn và ràng buộc nó với EventCommand và cập nhật giá trị của nó trong javascript. Nhưng tự hỏi liệu có thể làm tương tự trực tiếp với mô hình không?)

@sortnoun Tôi có quan điểm của bạn, var model = @Html.Raw(Json.Encode(Model));điều này sẽ tạo ra một đối tượng javascript model không có kết nối với Mô hình C # mà bạn chuyển đến chế độ xem. Nguyên vẹn sẽ không có Modelsau khi chế độ xem được hiển thị. Vì vậy, Biểu mẫu trong giao diện người dùng sẽ không có manh mối về thay đổi dữ liệu đối tượng javascript. Bây giờ bạn cần chuyển toàn bộ mô hình đã sửa đổi này cho bộ điều khiển thông qua AJAX, Hoặc bạn cần cập nhật giá trị của các điều khiển đầu vào bằng biểu mẫu bằng javascript.
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?đối với câu lệnh này .. không có EventCommand trong MVC, nó dành cho Webforms nơi có kết nối giữa các hành động của UI và máy chủ, Trong MVC tất cả đều tách biệt. Cách duy nhất để bạn tương tác với bộ điều khiển là thông qua AJAX hoặc Gửi mẫu hoặc Yêu cầu trang mới (cũng tải lại)
Rajshekar Reddy

21

hãy thử điều này: (bạn đã bỏ lỡ các trích dẫn duy nhất)

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

1
@JuanPieterse với dấu ngoặc kép cung cấp cho bạn một JSONtrích dẫn không thể cung cấp cho bạn a javascript Object. Kiểm tra câu trả lời của tôi trong cùng một chủ đề để biết thêm chi tiết. stackoverflow.com/a/41312348/2592042
Rajshekar Reddy

Điều đó không đúng, giải pháp @danmbuen đã hoạt động trong trường hợp của tôi, tôi gặp vấn đề và gói nó giữa các trích dẫn làm việc như một lá bùa, CẢM ƠN BẠN;)
Dimitri

4

Gói tài sản mô hình xung quanh parens làm việc cho tôi. Bạn vẫn gặp vấn đề tương tự với Visual Studio phàn nàn về dấu chấm phẩy, nhưng nó hoạt động.

var closedStatusId = @(Model.ClosedStatusId);

0

Nếu lỗi "ReferenceError: Model không được xác định" được nêu ra, thì bạn có thể thử sử dụng phương pháp sau:

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

Hi vọng điêu nay co ich...


0

Tôi biết quá muộn nhưng giải pháp này đang hoạt động hoàn hảo cho cả khung .net và lõi .net:

@ System.Web.HttpUtility.JavaScriptStringEncode ()

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.