Ответ 1
В mvc3 с бритвой @Html.Raw(Json.Encode(object))
кажется, делает трюк.
Я разработчик Java, новичок в .NET. Я работаю над проектом .NET MVC2, где я хочу иметь частичное представление, чтобы обернуть виджет. Каждый объект виджета JavaScript имеет объект данных JSON, который будет заполнен данными модели. Затем методы обновления этих данных привязываются к событиям, когда данные изменяются в виджете или эти данные изменяются в другом виджете.
Код выглядит примерно так:
MyController
:
virtual public ActionResult DisplaySomeWidget(int id) {
SomeModelView returnData = someDataMapper.getbyid(1);
return View(myview, returnData);
}
myview.ascx
:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<SomeModelView>" %>
<script type="text/javascript">
//creates base widget object;
var thisWidgetName = new Widget();
thisWidgetName.updateTable = function() {
// UpdatesData
};
$(document).ready(function () {
thisWidgetName.data = <% converttoJSON(model) %>
$(document).bind('DATA_CHANGED', thisWidgetName.updateTable());
});
</script>
<div><%:model.name%></div>
Чего я не знаю, так это как отправить данные как SomeModelView
и затем использовать их для заполнения виджета, а также для преобразования их в JSON. Я видел несколько действительно простых способов сделать это в контроллере, но не в представлении. Я полагаю, что это основной вопрос, но я собирался сделать это несколько часов.
В mvc3 с бритвой @Html.Raw(Json.Encode(object))
кажется, делает трюк.
Хорошо, вы только начали использовать MVC, и вы нашли свой первый главный недостаток.
Вы действительно не хотите преобразовывать его в JSON в представлении, и вы действительно не хотите его преобразовывать в контроллер, поскольку ни одно из этих мест не имеет смысла. К сожалению, вы застряли в этой ситуации.
Лучшее, что я нашел, это отправить JSON в представление в ViewModel, например:
var data = somedata;
var viewModel = new ViewModel();
var serializer = new JavaScriptSerializer();
viewModel.JsonData = serializer.Serialize(data);
return View("viewname", viewModel);
затем используйте
<%= Model.JsonData %>
в вашем представлении. Имейте в виду, что стандартный .NET JavaScriptSerializer довольно дерьмо.
делать это в контроллере, по крайней мере, делает его проверяемым (хотя и не совсем так, как указано выше), вы, вероятно, хотите взять ISerializer в качестве зависимости, чтобы вы могли его издеваться)
Обновить, что касается вашего JavaScript, было бы неплохо обернуть ВСЕ виджет JS, который у вас выше:
(
// all js here
)();
таким образом, если вы разместите несколько виджетов на странице, вы не столкнетесь с конфликтами (если вам не нужен доступ к методам из другого места на странице, но в этом случае вы должны регистрировать виджет с какой-либо инфраструктурой виджетов), В настоящее время это может быть не проблема, но было бы неплохо добавить скобки для экономии усилий в будущем, когда это станет требованием, а также хорошей практикой OO для инкапсуляции функциональности.
Я нашел довольно приятным сделать это так (использование в представлении):
@Html.HiddenJsonFor(m => m.TrackingTypes)
Вот соответствующий вспомогательный метод. Класс расширения:
public static class DataHelpers
{
public static MvcHtmlString HiddenJsonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
return HiddenJsonFor(htmlHelper, expression, (IDictionary<string, object>) null);
}
public static MvcHtmlString HiddenJsonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes)
{
return HiddenJsonFor(htmlHelper, expression, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static MvcHtmlString HiddenJsonFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes)
{
var name = ExpressionHelper.GetExpressionText(expression);
var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var tagBuilder = new TagBuilder("input");
tagBuilder.MergeAttributes(htmlAttributes);
tagBuilder.MergeAttribute("name", name);
tagBuilder.MergeAttribute("type", "hidden");
var json = JsonConvert.SerializeObject(metadata.Model);
tagBuilder.MergeAttribute("value", json);
return MvcHtmlString.Create(tagBuilder.ToString());
}
}
Это не супер-сложно, но решает проблему, где его поставить (в Контроллере или в представлении?) Ответ, очевидно: ни;)
Вы можете напрямую использовать Json
из действия,
Ваше действие будет примерно таким:
virtual public JsonResult DisplaySomeWidget(int id)
{
SomeModelView returnData = someDataMapper.getbyid(1);
return Json(returnData);
}
Edit
Просто увидел, что вы считаете, что это Model
в представлении, поэтому вышесказанное не является строго правильным, вам нужно сделать вызов Ajax
для метода контроллера, чтобы получить это, ascx
не будет то у меня есть модель как таковая, я оставлю свой код на всякий случай, если он вам полезна, и вы можете изменить вызов
@Html.Raw(Json.Encode(object)) можно использовать для преобразования View Modal Object в JSON
У Эндрю был отличный ответ, но я хотел немного подружиться. То, как это отличается, - это то, что мне нравится, когда мои модели ModelViews не содержат служебных данных. Просто данные для объекта. Кажется, что ViewData подходит для счета за данные головной части, но, конечно, я новичок в этом. Я предлагаю сделать что-то вроде этого.
контроллер
virtual public ActionResult DisplaySomeWidget(int id)
{
SomeModelView returnData = someDataMapper.getbyid(1);
var serializer = new JavaScriptSerializer();
ViewData["JSON"] = serializer.Serialize(returnData);
return View(myview, returnData);
}
Просмотр
//create base js object;
var myWidget= new Widget(); //Widget is a class with a public member variable called data.
myWidget.data= <%= ViewData["JSON"] %>;
Что это для вас значит, это дает вам те же данные в вашем JSON, что и в вашем ModelView, поэтому вы можете вернуть JSON обратно на ваш контроллер, и у него будут все части. Это похоже на просто запрос с помощью JSONRequest, однако для этого требуется один меньше вызовов, поэтому он экономит ваши накладные расходы. Кстати, это фанк для Dates, но это похоже на другой поток.
<htmltag id=’elementId’ data-ZZZZ’=’@Html.Raw(Json.Encode(Model))’ />
Обратитесь https://highspeedlowdrag.wordpress.com/2014/08/23/mvc-data-to-jquery-data/
Я сделал это ниже, и это работает как прелесть.
<input id="hdnElement" class="hdnElement" type="hidden" value='@Html.Raw(Json.Encode(Model))'>
Расширение отличного ответа от Dave. Вы можете создать простой HtmlHelper.
public static IHtmlString RenderAsJson(this HtmlHelper helper, object model)
{
return helper.Raw(Json.Encode(model));
}
И на ваш взгляд:
@Html.RenderAsJson(Model)
Таким образом, вы можете централизовать логику создания JSON, если по какой-то причине вы захотите позже изменить логику.