将 ajax actionlink 转换为引导按钮

Posted

技术标签:

【中文标题】将 ajax actionlink 转换为引导按钮【英文标题】:convert ajax actionlink as a bootstrap button 【发布时间】:2012-06-05 08:04:14 【问题描述】:

我有一个像这样的 ajax actionlink:

 <div style="float:left"> @Ajax.ActionLink("EMPLOYEE", "_PartialEmployeeIndex", "Employee", new AjaxOptions()  UpdateTargetId = "divToUpdate" ) </div>

我通常使用引导程序来设置按钮的样式:

  <input class="btn btn-info" type="button" value="Input">

或者像这样

 <button class="btn btn-success" type="submit"> </button>

那么如何将 ajax 操作链接转换为引导按钮?

我不想将类名放在包含 ajax actionlink 的 div 中,因为按钮显示为黑色字体并带有下划线...

我希望它显示为没有下划线和白色字体的实际按钮

【问题讨论】:

【参考方案1】:

您应该能够使用htmlAttributes 参数添加您想要的任何引导类:

@Ajax.ActionLink("EMPLOYEE", "_PartialEmployeeIndex", "Employee", new AjaxOptions()  UpdateTargetId = "divToUpdate" , new  @class = "btn" )

【讨论】:

但是如果我想在该按钮中包含一个跨度/图标怎么办?【参考方案2】:

如果你只想要一个图标,你可以这样做:

    @Ajax.ActionLink(" ", "Delete", new  id = 1 , new AjaxOptions
                                        
                                            Confirm = "Are you sure you wish to delete?",
                                            HttpMethod = "Delete",
                                            InsertionMode = InsertionMode.Replace,
                                            LoadingElementId = "div_loading"
                                        , new  @class = "glyphicon glyphicon-trash" )
名称ationlink不能为null或为空,所以我推荐一个空格。

【讨论】:

轰隆隆。你赢了。空间就是一切。不是一个按钮,但足够好。【参考方案3】:

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

最终结果是您可以拥有像 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 做一点小改动就可以接受新的按钮对象,因为它非常接近开始。首先选择器需要接受按钮和链接,然后 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)

【讨论】:

【参考方案4】:

如果您不想为每个 Bootstrap 元素分配适当的类,请查看TwitterBootstrapMVC

在带有 ajax 链接的示例中,您将编写如下内容:

@Ajax.ActionLink("EMPLOYEE", "_PartialEmployeeIndex", "Employee", ).AjaxOptions(new AjaxOptions()  UpdateTargetId = "divToUpdate" )

【讨论】:

【参考方案5】:

添加到特里回答,如果你想给按钮添加html,最好的方法是使用Javascript来附加html代码。 Ajax.Actionlink 的 linkText 参数会自动对您提供的任何文本进行编码,您无法避免这种情况(除了编写自己的帮助程序)。

像 JQuery append 或 prepend 这样的东西会起作用。

<div> 
@Ajax.ActionLink("EMPLOYEE", "_PartialEmployeeIndex", "Employee", new AjaxOptions()  UpdateTargetId = "divToUpdate" , new  @class = "btn btn-default my-custom-class" ) 
</div>

<script>
    $(".my-custom-class").prepend("<span class=\"glyphicon glyphicon-pencil\"></span>&nbsp; ");
</script>

【讨论】:

【参考方案6】:

另一种方法是使用 Ajax.BeginForm,它允许您直接输入 HTML。这假设您尚未进入表单。

@using (Ajax.BeginForm("EMPLOYEE", "_PartialEmployeeIndex", "Employee", new AjaxOptions()  UpdateTargetId = "divToUpdate" ))

    <button type="submit" id="EmployeeButton" title="Employee" aria-label="Employee Button">
        <span class="glyphicon glyphicon-trash"></span>
    </button>

【讨论】:

【参考方案7】:
@Ajax.ActionLink(" ", "EditUser/" + Model.Id, null, new AjaxOptions  
      OnSuccess = "userEditGet", 
      HttpMethod = "post", 
      LoadingElementId = "ajaxLoader" 
 ,new  @class = "btn btn-default glyphicon glyphicon-edit" )

【讨论】:

以上是关于将 ajax actionlink 转换为引导按钮的主要内容,如果未能解决你的问题,请参考以下文章

Ajax POST 使用引导验证器转换为 GET

在MVC3中,同一个页面有3个按钮是要用ajax异步刷新的,不想用@html.ActionLink,@html.BeginForm()的话,不行

Ajax.ActionLink 在表中的标题后插入?

如何将 Actionlink 组转换为下拉列表

MVC 5 Ajax.BeginForm Submit按钮调用当前页面而不是指定的Controller和Action的URL

使 html 链接 href 属性等于 Ajax.ActionLink