ASP.NET MVC - Объедините результат Json с ViewResult

Сокрытие закрытых методов и данных (инкапсуляция)

существует общая идиома в Python обозначения методов и других участников класса, которые не предназначаются, чтобы быть частью внешнего API класса путем давания им имен, которые запускаются с подчеркиваний. Это удобно и работает очень хорошо на практике, но это производит ложное впечатление, что Python не поддерживает истинную инкапсуляцию частного кода и/или данных. На самом деле Python автоматически дает Вам лексические закрытия , которые делают очень легким инкапсулировать данные намного большим количеством пуленепробиваемого способа, когда ситуация действительно гарантирует его. Вот изобретенный пример класса, который использует эту технику:

class MyClass(object):
  def __init__(self):

    privateData = {}

    self.publicData = 123

    def privateMethod(k):
      print privateData[k] + self.publicData

    def privilegedMethod():
      privateData['foo'] = "hello "
      privateMethod('foo')

    self.privilegedMethod = privilegedMethod

  def publicMethod(self):
    print self.publicData

И вот изобретенный пример его использования:

>>> obj = MyClass()
>>> obj.publicMethod()
123
>>> obj.publicData = 'World'
>>> obj.publicMethod()
World
>>> obj.privilegedMethod()
hello World
>>> obj.privateMethod()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'MyClass' object has no attribute 'privateMethod'
>>> obj.privateData
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'MyClass' object has no attribute 'privateData'

ключ - то, что privateMethod и privateData не действительно атрибуты obj вообще, таким образом, к ним нельзя получить доступ снаружи, и при этом они не обнаруживаются в dir() или подобный. Они - локальные переменные в конструкторе, абсолютно недоступном за пределами __init__. Однако из-за волшебства закрытий, они действительно на переменные экземпляра с тем же временем жизни как объект, с которым они связаны, даже при том, что нет никакого способа получить доступ к ним снаружи кроме (в этом примере) путем вызова privilegedMethod. Часто этот вид очень строгой инкапсуляции является излишеством, но иногда это действительно может быть очень удобно для хранения API или пространства имен, писклявого чистый.

В Python 2.x, единственный способ иметь изменяемое частное состояние с изменяемым объектом (таким как dict в этом примере). Многие люди отметили относительно того, насколько раздражающий это может быть. Python 3.x удалит это ограничение путем представления nonlocal ключевое слово, описанное в PEP 3104.

30
задан elado 25 July 2009 в 10:54
поделиться

3 ответа

Вы также можете преобразовать PartialViewResult в строку, а затем передать эту строку через JSON в ваше представление, отображая ее на вашей странице с помощью jQuery.

Вы можете увидеть это в этом сообщении: http://www.atlanticbt.com/blog/asp-net-mvc-using-ajax-json-and-partialviews/ .

Я создал расширение, чтобы упростить задачу:

public static class MvcHelpers
{
    public static string RenderPartialView(this Controller controller, string viewName, object model)
    {
        if (string.IsNullOrEmpty(viewName))
            viewName = controller.ControllerContext.RouteData.GetRequiredString("action");

        controller.ViewData.Model = model;
        using (var sw = new StringWriter())
        {
            ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
            var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
            viewResult.View.Render(viewContext, sw);

            return sw.GetStringBuilder().ToString();
        }
    }
}

В моем контроллере я называю его следующим образом:

const string msg = "Item succesfully updated!";
return new JsonResult
           {
               Data = new
                          {
                              success = true, 
                              message = msg,
                              view = this.RenderPartialView("ProductItemForm", model)
                          },
               JsonRequestBehavior = JsonRequestBehavior.AllowGet
           };

Где «this» - это контроллер в случае, «ProductItemForm» - это мое представление и «модель» это мой объект productItem :)

Надеюсь, это поможет;)

41
ответ дан 28 November 2019 в 00:08
поделиться

Это может быть немного хакерским (и я пишу в верхней части моей головы), но вы можете создать свой собственный подкласс ActionResult, а также реализовать ResultFilter, который перехватывает эти конкретные типы ActionResult и отображает соответствующие представления, заполняет JsonResult и возвращает его.

Например, вы можете определить:

public CompoundResult: ActionResult
{
    public string ViewName { get; set; }
    public JsonResult JsonResult { get; set; }
    public CompoundResult(string viewName, JsonResult jsonResult)
    {
       ViewName = viewName;
       JsonResult = jsonResult;
    }
}

, а затем в ResultFilter отобразить соответствующее представление и объединить его с соответствующее место в JsonResult и, наконец, вернуть JsonResult клиенту.

Помимо всего этого, вы можете изменить свой подход к тому, как вы это делаете, например. вы можете попробовать вернуть полное представление (например, HTML) из своего действия, часть которого является представлением, которое вы хотите вернуть, но которое также включает некоторую дополнительную информацию, которая в противном случае была бы в вашем объекте JSON. Вы можете извлечь соответствующие компоненты из возвращенного HTML, используя простые операции jQuery на стороне клиента.

0
ответ дан 28 November 2019 в 00:08
поделиться

В первом случае, я думаю, вы можете просто вернуть HTML, но встроить данные в возвращенную форму. Используйте jQuery для доступа к данным в вашем успешном обратном вызове.

$.ajax({
    url: '<%= Url.Action( "MyAction" )',
    dataType: 'html',
    data: $('form').serialize(),
    success: function(data) {
                $('form').html(data);
                var id = $('form').find('input#formId[type=hidden]').val();
             }
});

Во втором случае общий View, который принимает два или более ViewNames и использует RenderPartial, вероятно, является лучшим решением, чем возврат HTML через JSON.

Multiview.aspx

 ...
<% foreach (string viewName in Model.Views)
   {
       Html.RenderPartial( viewName );
   }
%>

] Затем в своем действии:

public ActionResult MyAction(...)
{
     ... set up model with data
     model.Views = new List<string> { "View1", "View2" };

     return View( "Multiview", model );
}
1
ответ дан 28 November 2019 в 00:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: