【问题标题】:MVC2 / MVC3 Html Helper or Editor Template solution required需要 MVC2 / MVC3 Html Helper 或 Editor Template 解决方案
【发布时间】:2012-05-22 13:31:59
【问题描述】:

我有一个运行良好的基于​​ jquery 的定制查找控件,但我希望将它封装成一个更整洁的解决方案。以下是 Razor 视图中包含的代码。在幕后还有一个名为“InitLookup”的定制 jquery 函数,它在运行时完成大部分工作。

   <script type="text/javascript">
       $(document).ready(function () {
           InitLookup('#txtDelegatedToLookup', '#Delegated_To_ID', '@Url.Action("ContactLookup", "marMIS")');
       });
   </script>
   @Html.HiddenFor(m => m.Delegated_To_ID)
   <input id="txtDelegatedToLookup" type="text" />

理想情况下,我想将其简化为一个更整洁、更可重用的解决方案,其中 javascript InitLookup() 是动态创建并封装在其中的,可能如下所示...

@Html.DynamicLookupFor(m => m.Delegated_To_ID, "ContactLookup", "marMIS")

...其中“marMIS”是控制器,“ContactLookup”是控制器方法。这些是用于在查找期间获取数据的地址。

我尝试在 /Views/Shared/EditorTemplates 文件夹中创建一个名为 DynamicLookup 的编辑器模板,但在使用 @Html.DynamicLookup(... em>

有谁愿意接受这个?干杯!

------------ App_Code 建议如下!原始问题的附录! --------------------------

好的,所以我已将代码复制到名为 CustomHelpers.cshtml 的新 App_Code 文件夹文件中。如何将 lambda 表达式传递到此处然后使用它?

@using System.Security.Policy
@using System.Web.Mvc.Html

@helper DynamicLookup(LAMBDAEXPR, CtrlId, Controller, Method) {
    @Html.HiddenFor(LAMBDAEXPR)
    <input id="txtDelegatedToLookup" type="text" />
    @Html.ValidationMessageFor(LAMBDAEXPR)  

    <script type="text/javascript">
        $(document).ready(function () {
            InitLookup(txtCtrlId, idCtrlId, '@Url.Action(Controller, Method)');
        });
    </script>            
}

【问题讨论】:

    标签: asp.net-mvc-3 asp.net-mvc-2 razor html-helper razor-declarative-helpers


    【解决方案1】:

    如果您想封装 javascript 部分,您可以创建一个 HtmlHelper 来生成所需的内容。

    如下所示:

    public static MvcHtmlString DynamicLookupFor(this HtmlHelper htmlHelper, string txtCtrlId, string idCtrlId, string controllerName, string actionName)
    {
        // create script tag
        var script = new TagBuilder("script");
    
        // generate script content
        var result = new StringBuilder();
        result.AppendLine("$(document).ready(function () {");
        result.Append("InitLookup(");
    
        result.Append("'" + txtCtrlId + "',");
        result.Append("'" + idCtrlId + "',");
    
        // generate action link
        var url = new UrlHelper(HttpContext.Current.Request.RequestContext);
        result.Append("'" + url.Action(actionName, controllerName));
    
        result.AppendLine("'});");
    
        script.InnerHtml = result.ToString();
        return MvcHtmlString.Create(script.ToString());
    }
    

    在您的视图中,您可以按如下方式调用助手:

    @Html.DynamicLookupFor("#txtDelegatedToLookup", "#Delegated_To_ID", "ContactLookup", "marMIS")
    

    不要忘记在 Views 文件夹 web.config 中注册帮助程序:

      <namespaces>
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Routing" />
        <add namespace="Names Space Of Helper"/>   
      </namespaces>
    

    【讨论】:

    • 这看起来与我现在正在尝试的非常接近。目前我出错的地方是尝试使用@Html。 o html。从助手内部。它的这个元素似乎是不可能的,即使我使用 System.Web.Mvc.Html 添加;到cs文件的头部...... @Html.HiddenFor(...... Html.HiddenFor(
    • 其实我现在可能有这个了。我可以从传入的 html 变量中访问这些方法。暂时把这个留给我吧。这里有很棒的想法,这就是我目前正在努力的路线。
    • 在发表评论时,我已经开始使用上述解决方案,但它确实有助于确认方法并产生一些想法。非常感谢杰西!!!
    【解决方案2】:

    好的,这就是我最终要做的事情。它确实非常好用!将来它需要一点点润色,它也为扩展它敞开了大门。例如,控件进行了验证,但它不会按照我的其余验证为自己着色,而只是显示文本验证消息。

    功能就是这样调用的...

    @Html.CustomLookupFor(m => m.Task_History.Delegated_To_ID, "txtDelegatedToLookup", @Url.Action("ContactLookup", "marMIS"), new { width = "250px" })
    

    ...并且需要在 razor 视图页面顶部使用 using 语句...

    @using Custom.MVC.Helpers;
    

    顺便说一句,有两件事...... jquery 1.7.2+ 和 jquery ui 1.8.16+ 是我开发这个时使用的! 此外,下面第一个代码部分中的功能包括 代码中的 javascript 功能,以及包含原始代码的注释部分 javascript 代码的格式很好。

    然后在后台有两段代码。这里的第一个是关于我最初的问题我正在寻求开发的可重用代码。它下面的第二个是服务器上的控制器方法。

    using System;
    using System.Linq.Expressions;
    using System.Text;
    using System.Web.Mvc;
    using System.Web.Mvc.Html;
    using System.Web.Routing;
    
    namespace Custom.MVC.Helpers
    {
        public static class CustomHtmlHelperExtensions
        {
            public static MvcHtmlString CustomLookupFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> exp, string id, string url, object options)
            {   
                var hidCtrlId = id + "_id"; 
    
                //Options
                var opt = new RouteValueDictionary(options);
                var textBoxWidth = (opt["width"] != null) ? opt["width"].ToString() : "";
                var textBoxVisibility = (opt["visibility"] != null) ? opt["visibility"].ToString() : ""; 
    
                //Construct the script fired when the document is fully loaded
                var sbScript = new StringBuilder();
                sbScript.Append("<script type='text/javascript'>");
                sbScript.Append("  function InitDynamicLookupFor(e,f){var g='#'+e;var h='#'+e+'_id';$(g).click(function(){$(g).val('');$(h).val('');$(h).trigger('change')});$(g).autocomplete({minLength:3,delay:100,autoFocus:true,autofill:true,mustMatch:true,matchContains:true,width:220,source:function(c,d){$.ajax({url:f,type:'POST',dataType:'json',data:{searchId:0,searchTerm:c.term,searchLimit:10},success:function(b){d($.map(b,function(a){return{id:a.id,value:a.value}}))}})},create:function(b,c){if($(h).val()!=''){$.ajax({url:f,type:'POST',dataType:'json',data:{searchId:$(h).val(),searchTerm:'',searchLimit:1},success:function(a){$(g).val(a[0].value);$(g).removeClass('DynamicLookupForNotSelected');$(g).addClass('DynamicLookupForSelected')}})}},select:function(a,b){$(h).val(b.item.id);$(g).val(b.item.value);$(g).removeClass('DynamicLookupForNotSelected');$(g).addClass('DynamicLookupForSelected');$(h).trigger('change');return false},open:function(a,b){$(h).val(null);$(g).removeClass('DynamicLookupForSelected');$(g).addClass('DynamicLookupForNotSelected')}});if($(h).val()==''){$(g).val('Type here to search!');$(g).removeClass('DynamicLookupForSelected');$(g).addClass('DynamicLookupForNotSelected')}}");
                sbScript.Append("  ");
                sbScript.Append("  $(document).ready(function () {");
                sbScript.Append("    InitDynamicLookupFor('" + id + "', '" + url + "');");
                sbScript.Append("  });");
                sbScript.Append("</script>");
    
                //Construct the HTML controls for the DynamicLookup and its validation
                var sbCtrls = new StringBuilder();
                sbCtrls.Append(html.HiddenFor(exp, new { id=hidCtrlId }));
                sbCtrls.Append("<input id='" + id + "' type='text' style='width:" + textBoxWidth + "; visibility:" + textBoxVisibility + ";' />");
                sbCtrls.Append(html.ValidationMessageFor(exp));
    
                //Return the lot back to the interface
                var retString = sbScript.ToString() + sbCtrls.ToString();
                return new MvcHtmlString(retString);
            }
    
        }
    }
    
                //*** This is the original javascript code before it is minified for use above!  DON'T DELETE! ***
                //
                //    function InitDynamicLookupFor(textBox, url) {
                //    var $textBox = '#' + textBox;
                //    var $hiddenId = '#' + textBox + '_id';
    
                //    $($textBox).click(function () {
                //        $($textBox).val('');
                //        $($hiddenId).val('');
                //        $($hiddenId).trigger('change');
                //    });
    
                //    $($textBox).autocomplete({
                //        minLength: 3,
                //        delay: 100,
                //        autoFocus: true,
                //        autofill: true,
                //        mustMatch: true,
                //        matchContains: true,
                //        width: 220,
                //        source: function (request, response) {
                //            $.ajax({
                //                url: url, type: 'POST', dataType: 'json',
                //                data: { searchId: 0, searchTerm: request.term, searchLimit: 10 },
                //                success: function (data) {
                //                    response($.map(data, function (item) {
                //                        return {
                //                            id: item.id,
                //                            value: item.value
                //                        };
                //                    }));
                //                }
                //            });
                //        },
                //        create: function (event, ui) {
                //            if ($($hiddenId).val() != '') {
                //                $.ajax({
                //                    url: url, type: 'POST', dataType: 'json',
                //                    data: { searchId: $($hiddenId).val(), searchTerm: '', searchLimit: 1 },
                //                    success: function (data) {
                //                        $($textBox).val(data[0].value);
                //                        $($textBox).removeClass('DynamicLookupForNotSelected');
                //                        $($textBox).addClass('DynamicLookupForSelected');
                //                    }
                //                });
                //            }
                //        },
                //        select: function (event, ui) {
                //            $($hiddenId).val(ui.item.id);
                //            $($textBox).val(ui.item.value);
                //            $($textBox).removeClass('DynamicLookupForNotSelected');
                //            $($textBox).addClass('DynamicLookupForSelected');
                //            $($hiddenId).trigger('change');
                //            return false;
                //        },
                //        open: function (event, ui) {
                //            $($hiddenId).val(null);
                //            $($textBox).removeClass('DynamicLookupForSelected');
                //            $($textBox).addClass('DynamicLookupForNotSelected');
                //        }
                //    });
    
                //    //If no value selected by now, indicate to the user how to use the control
                //    if ($($hiddenId).val() == '') {
                //        $($textBox).val('Type here to search!');
                //        $($textBox).removeClass('DynamicLookupForSelected');
                //        $($textBox).addClass('DynamicLookupForNotSelected');
                //    }
                //}
    

    服务器上的控制器方法...

    public JsonResult ContactLookup(int searchId, string searchTerm, int searchLimit)
        {
            //Prepare search filter from criteria entered
            var p = PredicateBuilder.True<vw_Contact_Verbose>();
            if (searchId != 0) p = p.And(x => x.Contact_ID == searchId); 
            if (searchTerm != "") p = p.And(x => x.Fullname.Contains(searchTerm));
    
            //Grab data
            var results =
                (from x in _mDb.ent.vw_Contact_Verbose.AsExpandable().Where(p).OrderBy("Fullname Desc").Take(searchLimit)
                 select new { id = x.Contact_ID, value = x.Fullname + " (" + x.Company + ")" }).ToArray();
    
            return Json(results, JsonRequestBehavior.AllowGet);
        }  
    

    我确实希望这个可重复使用的代码对其他人和我一样有用。这无疑使我的代码在剃刀视图中不那么冗长。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-31
      • 1970-01-01
      • 1970-01-01
      • 2023-01-26
      • 2023-03-22
      • 1970-01-01
      • 2017-10-02
      • 2015-06-04
      相关资源
      最近更新 更多