【问题标题】:Use MVC helpers inside jquery.tmpl templates在 jquery.tmpl 模板中使用 MVC 助手
【发布时间】:2011-10-22 18:38:36
【问题描述】:

我有一个简单的foreach 模板,在每个元素中我想要一个 ActionLink,但 ActionLink 需要发送一个 Id 来编辑元素。

要模板化的项目:

<div data-bind="template: {
                    name: 'postsTemplate',
                    foreach: posts
                    }">
</div>

模板:

<script id="postsTemplate" type="text/html">
<h2 data-bind="text: Title"></h2>

<p class="post-info">
    <p class="post-info" data-bind="text UserName"></p>
    <span data-bind="Body"></span>
    <p class="post-footer">
        @Html.ActionLink("Comments", "IndividualPost", "Post", null, null, "comments", new {id = })
    </p>
</p>
</script>

如何通过 ActionLink 发送实际帖子 Id?我的意思是,如何在不使用数据绑定的情况下访问帖子的 ID? (因为它是一个帮手)。

【问题讨论】:

  • Post 是您的视图模型的一部分吗?如果是,你不能说id= @model.Post.Id吗?
  • Posts 是一个 IEnumerable,然后序列化为 javascript,所以“posts”是一个 observableArray。你说的我做不到。

标签: asp.net-mvc knockout.js helper jquery-templates


【解决方案1】:

如果您要按照以下方式实现自己的 ActionLink 扩展:

public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText,
                                       string actionName, string controllerName,
                                       object routeValues,  bool noEncode)
    {
        var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
        var url = urlHelper.Action(actionName, controllerName, routeValues);

        if (noEncode) url = Uri.UnescapeDataString(url);

        var tagBuilder = new TagBuilder("a");

        tagBuilder.MergeAttribute("href", url);
        tagBuilder.InnerHtml = linkText;

        return MvcHtmlString.Create(tagBuilder.ToString(TagRenderMode.Normal));
    }

然后你可以让你的模板像:

<p class="post-info">
    <p class="post-info" data-bind="text UserName"></p>
    <span data-bind="Body"></span>
    <p class="post-footer">
        @Html.ActionLink("Comments (${CommentCount})", "IndividualPost", "Post", 
                         new {id = "${id}"}, true)
    </p>
</p>

生成的服务器端 html 如下所示:

<p class="post-info">
    <p class="post-info" data-bind="text UserName"></p>
    <span data-bind="Body"></span>
    <p class="post-footer">
       <a href="/Post/IndividualPost/${id}">Comments (${CommentCount})</a>
    </p>
</p>

在我看来,这又是一个完美的模板。

ActionLink 扩展的原因是普通的 Html.ActionLink 将您的 url 编码为 /Post/IndividualPost/%24%7Bid%7D 这不适用于模板

【讨论】:

  • 很好的解决方案! url = Uri.UnescapeDataString(url) 会将 url 转换为小写,因此 jquery tmpl 仅适用于小写变量。 url = HttpUtility.UrlDecode(url) 不会将其转换为小写。
【解决方案2】:

选项 1: - 您的帖子视图模型可能来自服务器,它可能包含链接。

{
title:'post title', 
commentsUrl:'/Indivdualpost/comments/123'
} 

在服务器上

 return new post { comment='post title', commentsUrl=Url.Action('Comments','Individualposts', new {id=1234}); }

然后在模板中渲染 cmets url:

 <a data-bind="attr: {href:commentsUrl}">comments</a>

选项 2: 使用表单的脚本

<form id="frm" action="@Url.Action("Comments","IndividualPost")>
<input type="hidden" name="id" id="postid"/>
<!-- template stuff -->
</form>

在模板中

<p class="post-footer">
    <a data-bind="click:function(){ $('#postid').val(${$id}); $('#frm').submit(); }">comments</a>
</p>

(点击属性很丑,应该使用绑定处理程序或视图模型函数(http://www.knockmeout.net/2011/08/simplifying-and-cleaning-up-views-in.html)来改进)

【讨论】:

  • 不错,但只是一种解决方法。我需要链接标题为“Comments” + CommentsCount,所以我需要将一个字符串与 post 属性连接起来。所以你的解决方案不起作用。也许淘汰赛还很年轻。
  • 好吧,对于其他事情我可以使用 ${CommentsCount} 但也可以很好地用于参数;(
  • 您可以选择在服务器或客户端上创建、构建您的帖子信息。在客户端上可以在 json 中提供 url。标题和计数也可以使用 databiding 添加,
猜你喜欢
  • 2014-01-03
  • 1970-01-01
  • 1970-01-01
  • 2014-05-12
  • 1970-01-01
  • 2013-06-19
  • 2014-06-20
  • 2014-08-12
  • 2012-01-13
相关资源
最近更新 更多