【问题标题】:Many modal windows with large strings许多带有大字符串的模态窗口
【发布时间】:2013-03-16 19:25:05
【问题描述】:

在我使用 twitter 引导程序的 .Net MVC 应用程序中,我有一个绘制许多字段的视图。每个字段的值是一个 100 个字符长的缩短字符串。原始字符串的长度总是超过 1000 个字符(有时是 100k 个字符)。

string long = result[i]; // really long string that's over 1000 characters long
string short = long.Substring(0, 99);
<section>
    <div class="row-fluid">
        <div class="span12">@short</div>
    </div>    
</section>

对于我绘制的每个字段,我需要一个链接,用户可以单击该链接以显示一个模式窗口,在该窗口中我显示非缩短文本。

所以我可能希望在同一页面上有 100 个指向模态窗口的链接,并且每个模态窗口都将显示自己的文本。

类似这样的:http://jqueryui.com/dialog/

但我的问题是:

1) 我将在同一页面上有很多模式对话框,所以我想我需要为每个对话框设置一个唯一的 ID。

2) 我必须将长文本(“string long”)传递给每个模态对话框。也许当我在客户端代码中绘制它们时我可以做到这一点,或者我可以通过将长文本发送到我的控制器来做到这一点。我不确定最好的方法是什么。

我一直在看这个:ASP.NET MVC modal dialog/popup best practice,但我不太明白选中的答案指的是什么(“午餐的对话建议”?)。

【问题讨论】:

  • 我不认为你的意思是串联:en.wikipedia.org/wiki/Concatenation
  • “Lunchy 的对话建议”可能是指由于某种原因被删除的评论。
  • @SoonDead:谢谢。是的,我不知道我为什么写串联。我知道那个词是什么意思。 :)

标签: jquery asp.net-mvc asp.net-ajax modal-dialog


【解决方案1】:

一个潜在的策略是让 html 只用于一个模式对话框,并将所有长版本的字符串保存在某种 javascript 数据结构中,比如哈希数组或其他东西。这将避免您的页面因数百个模式对话框而被 HTML 臃肿

然后,当用户单击“显示长版本”链接时 - 您有一些查询将模式对话框中的内部文本替换为从哈希数组中检索到的字符串的适当“长版本”和然后显示该对话框。

如果您想变得更高级 - 您只需在页面中加载字符串的短版本,当用户单击链接时,它将通过 AJAX 检索字符串的“长版本”。

Twitter Bootstrap 带有一个模态对话框,请参阅here,而 JQuery 有一些将 HTML 插入元素的方法 - 请参阅 here

如果您查看 Twitter 引导模式对话框的文档,您会发现它可以选择使用 remote: 选项通过 AJAX 远程加载数据。

这是一个粗略的示例,说明如何使用 Twitter 引导程序通过 AJAX 执行此操作

控制器

public ActionResult Index()
{
    var model = GetLongStrings(); 
    return View(model);
}

public ActionResult FindLongString(string shortString)
{
    var longStrings = GetLongStrings();
    var longStringToReturn = longStrings
                            .FirstOrDefault(x => x.StartsWith(shortString));

    return Content(longStringToReturn);
}

然后,您的视图将如下所示

@foreach (var result in results)
{
    var shortString = result.Substring(0, 5);
    <section>
        <div class="row-fluid">
            <div class="span12">@shortString</div>
            @Html.ActionLink("See long version", "FindLongString", 
                             new { shortString = shortString }, 
                             new { data_toggle = "modal", 
                                   data_target = "#myModal", 
                                   aria_hidden = "true" })
        </div>
    </section>
}

<div id="myModal" class="modal hide fade">
    <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h3>Modal header</h3>
    </div>
    <div class="modal-body">
    </div>
    <div class="modal-footer">
        <a href="#" class="btn"  data-dismiss="modal">Close</a>
    </div>
</div>

ActionLink 中的数据属性很重要,因为它们指示 Twitter Bootstrap 为您的对话框使用哪些选项。

如果每个字符串都有一个 ID,则可以改进代码示例 - FindLongString 可以接受 `int 作为参数,这意味着您可以在 ActionLink 中传递它。

【讨论】:

  • 看起来不错。谢谢。当我通过视图中的 ActionLink 调用控制器时,我已经有了“longString”,所以我看不出为什么我不能将 longString 传递给控制器​​,而不是在控制器中有一个函数试图找到长字符串。
  • 我试过这个,我没有传递短字符串,而是传递了长字符串(因为我在创建 ActionLink 时已经有了它,所以我不明白为什么我应该在控制器中获取它),但我收到 HTTP 错误,因为字符串太长:“请求过滤模块配置为拒绝查询字符串太长的请求。”。 URL 是localhost/MyView/FindLongString?longstring=...,然后是>1000 个字符的整个长字符串。所以不幸的是,这太长了。我正在考虑只打开另一个视图并在那里显示它。
  • 您不应将长字符串作为参数传递。 “FindLongString”操作的全部意义在于,您无需通过线路发送所有长文本。您打算在第一个响应中发送所有长字符串。
  • 我的代码只是一个粗略的示例,可以给你一些想法。关键是你不应该用你可能永远不需要的 100 个“长字符串”来填充你的 html。而是用“短字符串”填充它,并仅在需要时通过 AJAX 从服务器请求“长字符串”。我的方法依赖于您将“短字符串”传递给服务器以获得不理想的“长字符串” - 但我希望能够展示这个概念。根据@SoonDead 的回答,最好为每个字符串分配一个int ID 并将其传递给服务器。
【解决方案2】:

StanK 的回答正是你所需要的,所以如果它对你有帮助,请毫不犹豫地接受它。

我只是有一个观察结果:通过短字符串检索长字符串并不是很可靠。我的意思是理论上所有字符串都可以以相同的 100 个字符开头(所有字符串甚至可以相同:))。如果有 2 个以相同 100 个字符开头的字符串,则无论点击哪个短字符串,都只会返回第一个。

一个更可靠的方法是为每个字符串提供一个唯一的标识符。这可以是任何东西,只要它们是独一无二的。这取决于您的服务器端逻辑。

  • 如果字符串来自关系数据库,通常可以使用表的主键(或任何唯一键。最好在大多数表上使用唯一的增量 ID)。这种方法还可以产生非常快速和干净的数据库查询。但请记住,通过这种方式,您可以从数据库结构中揭示您可能想要的更多信息。
  • 如果字符串在有序列表中且顺序固定,则可以使用元素的索引。

因此,使用 StanK 的示例代码并为其引入数据库连接(在我的例子中是实体框架,但这可以是任何东西):

控制器动作:

public ActionResult Index()
{
    using (Context ctx = new MyEntities())
    {
        var model = ctx.Strings.Select(o => new { Id = o.Id, longString = o.String });
        return View(model);
    }

}

public ActionResult FindLongString(string id)
{
    using (Context ctx = new MyEntities())
    {
        var record = ctx.Strings.SingleOrDefault(o => o.Id == id);
        if (record == null)
        {
            throw new HttpException(404, "The long string cannot be found");
        }
        else
        {
            return record.String;
        }
    }
}

观点:

@foreach (var result in results)
{
    var shortString = result.String.Substring(0, 99);
    <section>
        <div class="row-fluid">
            <div class="span12">@shortString</div>
            @Html.ActionLink("See long version", "FindLongString", 
                             new { id = result.Id }, 
                             new { data_toggle = "modal", 
                                   data_target = "#myModal", 
                                   aria_hidden = "true" })
        </div>
    </section>
}

<div id="myModal" class="modal hide fade">
    <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h3>Modal header</h3>
    </div>
    <div class="modal-body">
    </div>
    <div class="modal-footer">
        <a href="#" class="btn"  data-dismiss="modal">Close</a>
    </div>
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-14
    • 1970-01-01
    • 2010-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多