backbone.js - 使用主干复杂模型渲染带有下划线模板引擎的 html 表

标签 backbone.js underscore.js

我正在尝试使用下划线模板引擎呈现 html 表。首先,我从服务器收到这样的 JSON 响应

{
    CurrentModel: {
        Heading: "Home",
        Id: "pages/193",
        Metadata: {
            Name: "Home",
            Title: null,
            Keywords: null,
            Description: null,
            DisplayInMenu: true,
            Published: "/Date(1334499539404)/",
            Changed: "/Date(1334499539404)/",
            ChangedBy: "Marcus",
            IsPublished: true,
            IsDeleted: false,
            Slug: null,
            Url: null,
            SortOrder: 0
        },
        Parent: null,
        Children: [
            "pages/226",
            "pages/257"
        ]
},
    Children: [
        {
            Heading: "Foo",
            MainBody: null,
            Id: "pages/226",
            Metadata: {
                Name: "I'm an article",
                Title: null,
                Keywords: null,
                Description: null,
                DisplayInMenu: true,
                Published: "/Date(1334511318838)/",
                Changed: "/Date(1334511318838)/",
                ChangedBy: "Marcus",
                IsPublished: true,
                IsDeleted: false,
                Slug: "i-m-an-article",
                Url: "i-m-an-article",
                SortOrder: 1
            },
            Parent: {},
            Children: [ ]
        },
        {
            Heading: "Bar",
            MainBody: null,
            Id: "pages/257",
            Metadata: {
                Name: "Foo",
                Title: null,
                Keywords: null,
                Description: null,
                DisplayInMenu: true,
                Published: "/Date(1334953500167)/",
                Changed: "/Date(1334953500167)/",
                ChangedBy: "Marcus",
                IsPublished: true,
                IsDeleted: false,
                Slug: "foo",
                Url: "foo",
                SortOrder: 2
            },
            Parent: {},
            Children: [ ]
        }
    ]
}

我正在寻找的 HTML 结果非常像这样,我从 CurrentModel 打印一些数据并遍历 Children 属性,最好是 tbody 中的每个 tr 应该是使用backbone.js 的 View ,以便我可以连接这个特定行的一些事件。
<table>
    <caption><%= CurrentModel.Metadata.Name %></caption>
    <thead>
        <tr>
            <th><span>Page name</span></th>                
            <th><span>Slug</span></th>
            <th><span>Published</span></th>
            <th><span>Changed</span></th>
        </tr>
    </thead>
    <tbody>
        <% _(Children).each(function(page) { %>
            <tr>
                <td><%= page.Metadata.Name %></td>
                <td><%= page.Metadata.Slug %></td>
                <td><%= page.Metadata.IsPublished %></td>
                <td><%= page.Metadata.Changed %></td>
            </tr>                    
        <% }); %>
    </tbody>
</table>

现在,我的问题是我的主干 View 和模型应该是什么样子,或者它不应该像这样使用?如果来自服务器的响应只是页面的集合,下面的 javascript 代码可以工作并为每个子项呈现一个 tr,我理解方式,但我不知道如何修改代码,以便它可以采用复杂的模型,然后呈现部件该模型在一个或两个 JavaScript View 中?

在我的 application.js 我有这个代码
pages: function () {
    this.pageList = new PageCollection();
    this.pageListView = new PageListView({ model: this.pageList });
    this.pageList.fetch();
}

其中 PageCollection 看起来像这样
var PageCollection = Backbone.Collection.extend({
    url: '/pages',
    model: Page
});

像这样的模型类
Page = Backbone.Model.extend({
    metadata: {
        name: null,
        title: null,
        keywords: null,
        description: null,
        displayInMenu: null,
        published: null,
        changed: null,
        changedBy: null,
        isPublished: null,
        isDeleted: null,
        slug: null,
        url: null,
        sortOrder: null
    },
    parent: {},
    children: [],
    ancestors: null,
    initialize: function () { }
});

页面 ListView
PageListView = Backbone.View.extend({
    tagName: 'table',
    initialize: function () {
        this.model.bind("reset", this.render, this);
    },
    render: function (eventName) {
        _.each(this.model.models, function (page) {
            $(this.el).append(new PageListItemView({ model: page }).render().el);
        }, this);
        return this;
    }
});

最后是 PageListItemView
PageListItemView = Backbone.View.extend({
    tagName: "tr",
    template: _.template($('#tpl-page-list-item').html()),
    events: {
        "click td input[type=checkbox]": "publish"
    },
    render: function (eventName) {
        $(this.el).html(this.template(this.model.toJSON()));
        return this;
    },
    publish: function (event) {
        alert('Publish');
    }
});

最佳答案

首先,我会将数据解析到集合中以获取页面列表,然后获取 CurrentModel定义 :

var PageCollection = Backbone.Collection.extend({
    url: '/pages',
    model: Page,

    parse: function(response) {
        this.CurrentModel=new Page(response.CurrentModel);
        return response.Children;
    }
});

然后,将行模板设置为
<script id="tpl-page-list-item" type="text/template">
    <tr>
        <td><%= Metadata.Name %></td>
        <td><%= Metadata.Slug %></td>
        <td><%= Metadata.IsPublished %></td>
        <td><%= Metadata.Changed %></td>
        <td><input type='checkbox' /></td>
    </tr>
</script>

你可以或多或少地定义你的观点
var PageListItemView = Backbone.View.extend({
    template: _.template($('#tpl-page-list-item').html()),
    events: {
        "click input[type=checkbox]": "publish"
    },
    render: function (eventName) {
       var html=this.template(this.model.toJSON());
       this.setElement($(html));
       return this;
    },
    publish: function () {
        console.log(this.model.get("Metadata").Name);
    }
});

var PageListView = Backbone.View.extend({
    tagName: 'table',
    initialize: function () {
        this.collection.bind("reset", this.render, this);
    },
    render: function (eventName) {
        this.$el.empty();

        this.collection.each(function(page) {
            var pageview=new PageListItemView({ model: page });
            var $tr=pageview.render().$el;           
            this.$el.append($tr);
        },this);

        return this;
    }
});

初始化集合和 View ,获取数据,你应该有与这个 Fiddle 等效的东西:http://jsfiddle.net/NtmB4/
var coll=new PageCollection();
var view=new PageListView({collection:coll})
$("body").append(view.render().el);

coll.fetch();

以及与您的完整模板相对应的 fiddle http://jsfiddle.net/NtmB4/2/

关于backbone.js - 使用主干复杂模型渲染带有下划线模板引擎的 html 表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10257401/

相关文章:

javascript - 从事件中获取数据属性

javascript - 如何根据内部属性过滤 JSON 树

javascript - 如何使用下划线根据自定义排序顺序对对象数组进行排序

javascript - 如何使用 underscore.js 的 reduce 方法?

javascript - Underscore.js 的each 方法中的+obj.length 是什么意思?

javascript - 如何使用underscore.js对文本混合数字进行排序

javascript - 循环 JSON 并将内容分成三列

javascript - 了解 Backone js 路由与查询参数

backbone.js - Backbone > 多个路由器和 History.start

json - Backbone.js 使用 post 变量同步,而不是 json