【问题标题】:Is it possible to create a partial view as independent "widget"?是否可以将部分视图创建为独立的“小部件”?
【发布时间】:2014-06-03 12:58:27
【问题描述】:

使用旧的 ASP.NET,我们可以轻松地创建用户控件 (.ascx),事实上,许多控件完全独立于当前视图。我想知道MVC是否可以做到这一点?

我需要显示简单的用户列表,问题是 - 此列表应该显示在我网站上的多个位置。虽然我可以简单地修改我的视图模型,并向它们添加“小部件”模型,但我想避免这种情况。最好我希望我的用户列表只需要以下内容:

@Html.Partial("Link/To/My/List")

要包含在其他视图中 - 列表的模型必须以其他方式填充。我想在我的部分中使用 AJAX,但这似乎是个坏主意。有没有其他方法可以解决它,或者它只是一个打破 MVC 假设的坏主意?

【问题讨论】:

    标签: asp.net-mvc partial-views


    【解决方案1】:

    您可以使用 RenderAction 方法来渲染 Partial 视图。部分视图可以关联到与调用页面的模型不同的模型

    从视图中调用操作方法

    @{Html.RenderAction("SomeAction", "SomeController");} 
    

    Action 方法返回局部视图

    public ActionResult SomeAction()
            {
                //Construct SomeModel here..  
                return PartialView("SomeView", SomeModel);
            }
    

    【讨论】:

    • 如果您不希望有人在视图之外(直接从 Web 浏览器)意外调用此局部视图,您可以将 ChildActionOnlyAttribute 添加到方法中。
    • @ErikPhilips:这很好用,但是 - 是否也可以包含 js 脚本? For example - assuming we have a "widget" with drop down box, when option is selected widget should be reloaded via ajax.虽然这很容易做到,但它需要我们在使用我们的小部件的主视图中包含脚本 - 有没有办法将脚本与部分视图一起包含?
    • @ErikPhilips:再次感谢 - 我认为这可以解决问题。为什么来自 MS 的人必须做出如此奇怪的设计决定(我猜是试图保护开发人员免受自己的伤害?)我无法理解。
    • 我个人的看法是完全相反(至少在这种情况下)。它只是归结为Why doesn't feature X exist?
    【解决方案2】:

    您可以通过在局部视图中嵌入脚本块来编写封装“小部件”的局部视图。将脚本块包装在 div 中是将标记和初始化脚本一起包装在局部视图小部件中的一种简洁方法。例如,我可能有一个名为“_WidgetPartial”的局部视图,我在整个站点中都使用它。如果我将其放在母版页上的两个位置,它应该可以正常工作,并且我不希望不必在母版页中编写逻辑来初始化小部件。

    您可能希望将小部件编写为某种 jQuery 插件,然后脚本块变成一个简单的单行来初始化它。局部视图看起来像...

    <div id="widgetWrapper">
    
        <ul class="widget">
        </ul>
    
        <script>
            $(document).ready(function() {
                $("ul.widget").widget(...);
            });
        </script>
    </div>
    

    如果您永远不会在一个页面中多次使用它,它很简单,否则,包装代码使其不会执行两次。见下文。为了 Stack Overflow sn-ps,我通过在代码 sn-p 中重复两次局部视图来模拟它,以表示在母版页中包含两次局部视图小部件。

    我的母版页可能如下所示:

    <div id="left-nav">
       @Html.Partial("_WidgetPartial")           
    </div>
    
    <div id="body">
    </div>
    
    <div id="right-nav">
       @Html.Partial("_WidgetPartial")
    </div>
    

    例子:

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <!-- Self-contained partial view containing widget -->
    
    <div id="widgetDiv" class="panel panel-default">
    
        <div class="panel-heading">Event Dates</div>
        <div class="panel panel-group">
           <ul class="widget">
             <!-- These will load dynamically -->
           </ul>
        </div>
    
        <script>
            $(document).ready(function() {
    
                // Run this once only in case widget is on page more than once
                if(typeof $widget == 'undefined') {
                    $widget = $("ul.widget"); // could be more than one
                    // mock data to simulate an ajax call
                    var data = [
                       {Description: "March", StartDate: "03/01/2015"},
                       {Description: "April", StartDate: "04/01/2015"},
                       {Description: "May", StartDate: "05/01/2015"}
                    ];
    
                    $.each($widget, function(w, widget) {
                        // might be an $.ajax call
                        $.each(data, function(i, row) {
                            $(widget).append("<li><a href='/Widget/Search?startDate=" + row.StartDate + "'>" + row.Description + "</a></li>");
                        });
                    });
                }
            });
        </script>
    </div>
    <!-- End of widget / partial view -->
    
    
    
    <!-- Second copy of above for sake of example snippet -->
    <!-- No need to read further -->
    
    
    
    
    
    
    
    
    
    <!-- Self-contained partial view containing widget -->
    
    <div id="widgetDiv" class="panel panel-default">
    
        <div class="panel-heading">Event Dates</div>
        <div class="panel panel-group">
           <ul class="tinylist nav nav-sidebar widget">
             <!-- These will load dynamically -->
           </ul>
        </div>
    
        <script>
            $(document).ready(function() {
    
                // Run this once only in case widget is on page more than once
                if(typeof $widget == 'undefined') {
                    $widget = $("ul.widget"); // could be more than one
                    // mock data to simulate an ajax call
                    var data = [
                       {Description: "March", StartDate: "03/01/2015"},
                       {Description: "April", StartDate: "04/01/2015"},
                       {Description: "May", StartDate: "05/01/2015"}
                    ];
    
                    $.each($widget, function(w, widget) {
                        // might be an $.ajax call
                        $.each(data, function(i, row) {
                            $(widget).append("<li><a href='/Widget/Search?startDate=" + row.StartDate + "'>" + row.Description + "</a></li>");
                        });
                    });
                }
            });
        </script>
    </div>
    <!-- End of widget / partial view -->

    【讨论】:

      猜你喜欢
      • 2017-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-20
      • 1970-01-01
      • 1970-01-01
      • 2012-06-21
      相关资源
      最近更新 更多