0

我想对这个问题提出一些建议。我有一个显示许多用户的视图页面。一种视图是在用户图像的网格(类似画廊)中显示用户。第二个视图是在列表布局中显示相同的用户,但按他们的名字显示。我将在页面上有一个切换按钮来在两者之间切换。最好的方法是什么?有两个单独的视图页面或有某种部分视图?

在下面的建议后更新代码

<div data-bind="template: {name:'grid-template'}"></div>
<div data-bind="template: {name:'list-template'}"></div>

<script style="float:left"  type="text/html" id ="grid-template">
    <section " style="width:100%; float:left">
    <section id="users" data-bind="foreach: Users">
        <div id="nameImage">
            <figure id="content">
                <img width="158" height="158" alt="Gravatar" data-bind="attr:{src: GravatarUrl}"/>
                <figcaption>
                    <a title="Email" id="emailIcon" class="icon-envelope icon-white" data-bind="attr:{'href':'mailto:' + Email()}"></a>
                    <a title="Profile" id="profileIcon" class="icon-user icon-white"></a>
                </figcaption>
            </figure>
            <p data-bind="text:Name"></p>
            </div>
        </section>
    </section>
</script>

<script style="float:left" type="text/html" id="list-template">
        <div data-bind="foreach: Users">
            <div style="width:60%; float:left; margin:10px; height:58px">
                <img style="float:left; margin-right:5px" width="58" height="58" alt="Gravatar" data-bind="attr:{src: GravatarUrl}"/>
                <p style="height:58px; float:left; vertical-align:central" data-bind="text:Name"></p>
                <a style="float:right"  title="Profile"  class="icon-user icon-black"></a>
                <a style="float:right"  title="Email" class="icon-envelope icon-black" data-bind="attr:{'href':'mailto:' + Email()}"></a>
            </div>
        </div>
</script>

淘汰赛脚本文件

$.views.User.UserViewModel = function (data) {
        var self = this;
        self.Name = ko.observable(data.Name);
        self.Email = ko.observable(data.Email);
        self.ContentRole = ko.observable(data.ContentRole);
        self.MD5Email = ko.observable(data.MD5Email);
        self.GravatarUrl = ko.computed(function () {
           return 'http://www.gravatar.com/avatar/' + self.MD5Email() + '?s=300&d=identicon&r=G';
        });
        self.renderMode = ko.observable('grid');
        self.displayTemplate = ko.computed(function () {
            return self.renderMode() + '-layout-template';
        });

    };
4

1 回答 1

1

就个人而言,我喜欢干净的、独立的、小的局部视图,尤其是当它是常规的 HTTP POST 时。
但是,基于我在下面所做的假设,我认为我可以提出更好的实现设计。

我的假设

你有

  1. Index.cshtml 显示用户列表的父视图。
  2. 包含您的用户列表的 JSON 对象数组
  3. 根据我所看到的,您正在使用 KnockoutJS。
    阅读KnockoutJS 模板绑定,尤其是“注意 5:动态选择使用哪个模板”部分。

如果你使用KnockoutJS或类似的东西,它会让你做你正在做的事情变得更容易。
您只需在两个渲染模板之间切换。

<script type="text/html" id="gallery-layout-template"> ... </script>
<script type="text/html" id="listing-layout-template"> ... </script>

<div id="divOutputContainer"
     data-bind="template: { name: displayTemplate, foreach: users }"></div>

<script type="text/javascript">
$(document).ready(function() {

    // I am just writing out a dummy User array here.
    // Render out your User Array JSON encoded using JSON.NET.
    var myUsers = [
        { "id" : 1, "name": "User 1" },
        { "id" : 2, "name": "User 2" }
    ];

    // here is your KnockoutJS View Model "class"
    function MyKoViewModel(users) {
        var self = this;
        self.users = ko.observableArray(users);

        // Toggle this renderMode observable's value
        // between 'listing' and 'gallery' via your Toggle button click event handler
        self.renderMode = ko.observable( 'gallery' );

        self.displayTemplate = function(user) {
            // this will return 'gallery-layout-template' or 'listing-layout-template'
            return self.renderMode() + '-layout-template';
        }
    }

    ko.applyBindings( new MyKoViewModel( myUsers ) );
});
</script>

因此,使用该技术,您无需每次都调用 AJAX来使用不同的渲染模板刷新视图。
您拥有想要显示为客户端 JavaScript KnockoutJS 视图模型的所有数据。
然后,只需使用 KnockoutJS 切换客户端渲染模板。

必须更有效率:-)

笔记

我有一种感觉,您可能必须像这样将ko.computed()用于MyKoViewModel'sdisplayTemplate()函数。

self.displayTemplate = ko.computed(function() {
    return self.renderMode() + '-layout-template';
}
于 2013-04-09T06:11:59.530 回答