答案的内容
1) 如何在.cshtml文件中的Javascript/Jquery代码块中访问Model数据
2) 如何在.js文件中的Javascript/Jquery代码块中访问Model数据
如何在.cshtml文件中的Javascript/Jquery代码块中访问模型数据
有两种类型的 c# 变量 (Model) 分配给 JavaScript 变量。
-
属性分配 - 基本数据类型,例如
int、string、DateTime(例如:Model.Name)
-
对象分配 - 自定义或内置类(例如:
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';
结果是有效的,所以用引号将属性赋值给我们提供了有效的语法。但请注意,Number 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 字符串上使用 @Html.Raw() 确实向我们展示了一些变化。 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 数据现在已损坏,这将破坏脚本。问题是因为我们使用单引号 ' 来包装数据,甚至数据也有单引号。
我们可以通过 2 种方法来克服这个问题。
1) 使用双引号 " " 包裹 HTML 部分。由于内部数据只有单引号。 (确保用双引号括起来后数据中也没有")
var IconHtml = "@Html.Raw(Model.UserIconHTML)";
2) 转义服务器端代码中的字符含义。喜欢
UserIconHTML = "<i class=\"fa fa-users\"></i>"
属性分配结束
- 对非数字数据类型使用引号。
- 数字数据类型不要使用引号。
- 使用
Html.Raw 按原样解释您的 HTML 数据。
- 注意您的 HTML 数据,以便在服务器端转义引号含义,或者在分配给 javascript 变量期间使用与数据中不同的引号。
对象赋值
让我们使用不同的语法进行赋值并观察结果。
1) 没有将对象赋值用引号括起来。
var userObj = @Model;
当您将 c# 对象分配给 javascript 变量时,将分配该对象的 .ToString() 的值。因此有上述结果。
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 = {"Name":"Raj",
"IsAuthenticated":true,
"LoginDateTime":"\/Date(1482572875150)\/",
"Age":26,
"UserIconHTML":"\u003ci class=\"fa fa-users\"\u003e\u003c/i\u003e"
};
我们确实看到了一些变化,我们看到我们的模型被解释为一个对象。但是我们将这些特殊字符更改为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) format 和 JSON 不包含 date 类型。解决此问题的其他选项是添加另一行代码以单独使用 javascipt Date() 对象处理此类型
var userObj.LoginDateTime = new Date('@Html.Raw(Model.LoginDateTime)');
//without Json.Encode
如何在.js文件中的Javascript/Jquery代码块中访问模型数据
Razor 语法在 .js 文件中没有意义,因此我们不能直接在 .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) 使用 function() 或 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 函数未定义。
还要注意,该函数也必须在全局范围内。因此,无论哪种解决方案,我们都必须与全球范围内的玩家打交道。