1

在 ASP .Net MVC3 中,如何获取用户输入的输入值并处理单击按钮以调用控制器,返回一个新的模型实体,该实体使用其属性值更新其他表单输入值,而无需重新加载整个页面?

脚步:

  • 输入实体 ID。
  • 点击“搜索”
  • 输入的值被提交给控制器,控制器查询实体框架以返回一个实体 - 具有提供的 Id。
  • 找到的实体返回到调用页面。
  • 其他表单输入使用匹配的属性值更新其值。

我会在几秒钟内在 Web 窗体中完成这项工作,但对 MVC3 来说是新手......嗯......很有趣 :) 我认为这可能与 Ajax.ActionLink 有关?我看到的示例处理提交和保存数据。

理查德

4

3 回答 3

3

这就是使用 MVC3 进行 Ajax 发布的方法。OnSuccess在您的情况下,您根据来自服务器的响应更新回调函数上的表单字段。

步骤1

确保您已经引用了 jQuery Ajax 库

<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" type="text/javascript"></script>

第2步

在视图中使用 Ajax.BeginForm 辅助方法来生成 Ajax 感知表单。还提供了一个OnSuccessjavascript回调函数

@using(Ajax.BeginForm("Search",new AjaxOptions
{
  HttpMethod = "Post",    
  OnSuccess = "Loaded"    
}))
{
   <input type="text" name="q" />
   <button type="submit" value="Search">Search</button>
}

<script type="text/javascript">
   function Loaded(result) {
      alert('result ' + result.Name);
   }
</script>

第 3 步

在 action 方法中,进行业务处理并返回 JSON 结果。在此示例中,我只是返回了一个将查询附加到名称的模型。

[HttpPost]
public ActionResult Search(string q)
{
    return Json(new SampleViewModel { Age = 10 , Name = "John " + q });
}
于 2012-05-10T04:18:06.460 回答
1

您可以简单地使用 jquery ajax 方法来调用该操作,并让该操作返回您需要的任何值。然后,您可以使用返回的值通过 javascript 更新其他字段。

 $('#button').click(function(){
    $.ajax({
        url: 'controller/action.aspx',
        success: function(data) {
           $('.result').html(data);
        }
     });
 });

这是非常通用的解决方案,因为您没有提供任何代码,因此很难具体说明。您可能想要设置数据类型,具体取决于您发回的内容。一个流行的选择是 json。

见这里:http ://api.jquery.com/jQuery.ajax/

于 2012-05-11T01:46:26.567 回答
0

如果您想要一个实际的 Ajaxbutton元素,而不是样式 hack 或 JQuery,它也是可能的,但有点复杂。遗憾的是,MS 尚未选择将 ActionButton 添加到 Html 和 Ajax 帮助程序,因为当您删除私有支持方法的重复时,差异实际上非常小(您只需要下面显示的ActionButton和方法)。GenerateButton

最终结果是您可以拥有像 ajax 动作链接一样触发的真实按钮:

例如

@Ajax.ActionButton("Delete", "Delete", "document", 
     new { id = ViewBag.Id }, 
     new AjaxOptions() 
     { 
         Confirm="Do you really want to delete this file?", 
         HttpMethod = "Get", 
         UpdateTargetId = "documentlist" }, 
         new { id = "RefreshDocuments" 
     })

1.创建一个AjaxHelper扩展

下面的代码基于 AjaxExtensions 类的反编译,因为许多必需的帮助方法未在 HtmlHelper 上公开。

public static partial class AjaxExtensions
{
    public static MvcHtmlString ActionButton(this AjaxHelper ajaxHelper, string buttonText, string actionName, string controllerName, object routeValuesBlah, AjaxOptions ajaxOptions, object htmlAttributesBlah)
    {
        // Convert generic objects to specific collections
        RouteValueDictionary routeValues = new RouteValueDictionary(routeValuesBlah);
        RouteValueDictionary htmlAttributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributesBlah);

        if (string.IsNullOrEmpty(buttonText))
            throw new ArgumentException("Button text must be provided");
        string targetUrl = UrlHelper.GenerateUrl((string)null, actionName, controllerName, routeValues, ajaxHelper.RouteCollection, ajaxHelper.ViewContext.RequestContext, true);
        return MvcHtmlString.Create(GenerateButton(ajaxHelper, buttonText, targetUrl, AjaxExtensions.GetAjaxOptions(ajaxOptions), htmlAttributes));
    }

    public static string GenerateButton(AjaxHelper ajaxHelper, string linkText, string targetUrl, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes)
    {
        TagBuilder tagBuilder = new TagBuilder("input");
        tagBuilder.MergeAttribute("value", linkText);
        tagBuilder.MergeAttributes<string, object>(htmlAttributes);
        tagBuilder.MergeAttribute("href", targetUrl);
        tagBuilder.MergeAttribute("type", "button");
        if (ajaxHelper.ViewContext.UnobtrusiveJavaScriptEnabled)
            tagBuilder.MergeAttributes<string, object>(ajaxOptions.ToUnobtrusiveHtmlAttributes());
        else
            tagBuilder.MergeAttribute("onclick", AjaxExtensions.GenerateAjaxScript(ajaxOptions, "Sys.Mvc.AsyncHyperlink.handleClick(this, new Sys.UI.DomEvent(event), {0});"));
        return tagBuilder.ToString(TagRenderMode.Normal);
    }

    private static string GenerateAjaxScript(AjaxOptions ajaxOptions, string scriptFormat)
    {
        string str = ajaxOptions.ToJavascriptString();
        return string.Format((IFormatProvider)CultureInfo.InvariantCulture, scriptFormat, new object[1] { str });
    }

    private static AjaxOptions GetAjaxOptions(AjaxOptions ajaxOptions)
    {
        if (ajaxOptions == null)
            return new AjaxOptions();
        else
            return ajaxOptions;
    }

    public static string ToJavascriptString(this AjaxOptions ajaxOptions)
    {
        StringBuilder stringBuilder = new StringBuilder("{");
        stringBuilder.Append(string.Format((IFormatProvider)CultureInfo.InvariantCulture, " insertionMode: {0},", new object[1]
        {
             ajaxOptions.InsertionModeString()
        }));
        stringBuilder.Append(ajaxOptions.PropertyStringIfSpecified("confirm", ajaxOptions.Confirm));
        stringBuilder.Append(ajaxOptions.PropertyStringIfSpecified("httpMethod", ajaxOptions.HttpMethod));
        stringBuilder.Append(ajaxOptions.PropertyStringIfSpecified("loadingElementId", ajaxOptions.LoadingElementId));
        stringBuilder.Append(ajaxOptions.PropertyStringIfSpecified("updateTargetId", ajaxOptions.UpdateTargetId));
        stringBuilder.Append(ajaxOptions.PropertyStringIfSpecified("url", ajaxOptions.Url));
        stringBuilder.Append(ajaxOptions.EventStringIfSpecified("onBegin", ajaxOptions.OnBegin));
        stringBuilder.Append(ajaxOptions.EventStringIfSpecified("onComplete", ajaxOptions.OnComplete));
        stringBuilder.Append(ajaxOptions.EventStringIfSpecified("onFailure", ajaxOptions.OnFailure));
        stringBuilder.Append(ajaxOptions.EventStringIfSpecified("onSuccess", ajaxOptions.OnSuccess));
        --stringBuilder.Length;
        stringBuilder.Append(" }");
        return ((object)stringBuilder).ToString();
    }

    public static string InsertionModeString(this AjaxOptions ajaxOptions)
    {
        switch (ajaxOptions.InsertionMode)
        {
            case InsertionMode.Replace:
                return "Sys.Mvc.InsertionMode.replace";
            case InsertionMode.InsertBefore:
                return "Sys.Mvc.InsertionMode.insertBefore";
            case InsertionMode.InsertAfter:
                return "Sys.Mvc.InsertionMode.insertAfter";
            default:
                return ((int)ajaxOptions.InsertionMode).ToString((IFormatProvider)CultureInfo.InvariantCulture);
        }
    }

    public static string EventStringIfSpecified(this AjaxOptions ajaxOptions, string propertyName, string handler)
    {
        if (string.IsNullOrEmpty(handler))
            return string.Empty;
        return string.Format((IFormatProvider)CultureInfo.InvariantCulture, " {0}: Function.createDelegate(this, {1}),",
            new object[2]
              {
                propertyName,
                handler
              });
    }

    public static string PropertyStringIfSpecified(this AjaxOptions ajaxOptions, string propertyName, string propertyValue)
    {
        if (string.IsNullOrEmpty(propertyValue))
            return string.Empty;
        string str = propertyValue.Replace("'", "\\'");
        return string.Format((IFormatProvider)CultureInfo.InvariantCulture, " {0}: '{1}',",
            new object[2]
              {
                propertyName,
                str
              });
    }
}

2.修改jquery.unobtrusive-ajax.js

只需要对 jquery.unobtrusive-ajax.js 的 JQuery 进行小的更改即可接受新的按钮对象,因为它非常接近开始。首先,选择器需要接受 ajax 按钮和链接,然后 href 需要来自一个属性,以便非链接可以提供它(不严格兼容浏览器,但目前可以使用)。

$(document).on("click", "input[data-ajax=true],a[data-ajax=true]", function (evt) {
        evt.preventDefault();
        asyncRequest(this, {
            url: $(this).attr("href"),
            type: "GET",
            data: []
        });
    });

*注意:这是使用截至回答日期的所有内容的最新版本(MVC 5)

于 2014-01-27T09:05:44.333 回答