Backbone JS多级导航示例

时间:2011-04-01 22:41:22

标签: javascript url controller backbone.js underscore.js

我正在尝试构建一个可靠的Backbone JS实验,其中我有一个包含我的页面的本地JSON数据文件(无论如何我正在做的项目有这样的要求)。我编写了这个例子,所以我可以在页面数据中拥有无穷无尽的嵌套子页面。它似乎工作得很好。但是当涉及到URL时,我有点卡住了。

如何处理这个多级导航示例完全动态的URL?我的意思是,正确使用模型和集合的url属性为所有顶级和嵌套元素构造正确的URL。它甚至可能吗?我只是想不出怎么做。

查看我现在所处位置的现场演示: http://littlejim.co.uk/code/backbone/multiple-level-navigation-experiment/

这样更简单,源代码如下......

的index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Multiple Level Navigation Experiment</title>
    <script type="text/javascript" src="../../media/scripts/jquery-1.5.1.min.js"></script>
    <script type="text/javascript" src="../../media/scripts/underscore-min.js"></script>
    <script type="text/javascript" src="../../media/scripts/backbone-min.js"></script>
    <script type="text/javascript" src="application.js"></script>
    <script type="text/javascript">
    // wait for the DOM to load
    $(document).ready(function() {
        App.initialize();
    });
    </script>
</head>
<body>
    <div id="header">
        <h1>Multiple Level Navigation Experiment</h1>
        <p>Want to get this page structure pulled from JSON locally and have a fully functional multiple level nested navigation with correct anchors.</p>
    </div>
    <div id="article">
        <!-- dynamic content here -->
    </div>
</body>
</html>

content.json

{
"pages": [
    {
    "id": 1,
    "title": "Home",
    "slug": "home"
    },
    {
    "id": 2,
    "title": "Services",
    "slug": "services",
    "subpages": [
        {
        "id": 1,
        "title": "Details",
        "slug": "details",
        "subpages": [
            {
            "id": 1,
            "title": "This",
            "slug": "this"
            },
            {
            "id": 2,
            "title": "That",
            "slug": "that"
            }
        ]
        },
        {
        "id": 2,
        "title": "Honest Service",
        "slug": "honest-service"
        },
        {
        "id": 3,
        "title": "What We Do",
        "slug": "what-we-do"
        }
        ]
    },
    {
    "id": 3,
    "title": "Contact Us",
    "slug": "contact-us"
    }
]
}

的application.js

// global app class
window.App = {
    Data: {},
    Controller: {},
    Model: {},
    Collection: {},
    View: {},
    initialize : function () {
        $.ajax({
            url: "data/content.json",
            dataType: "json",
            success: function(json) {
                App.Data.Pages = json.pages;
                new App.Controller.Main();
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                console.log(errorThrown);
            }
        });
    }
}

// main controller class
// when called it should have 'data' in JSON format passed to it
App.Controller.Main = Backbone.Controller.extend({
    initialize: function() {
        var pagesCollection = new App.Collection.Pages(App.Data.Pages);
        var pagesView = new App.View.Pages({collection: pagesCollection});
        $('#article').html(pagesView.render().el);
    }
});

// pages model class
App.Model.Page = Backbone.Model.extend({
    initialize: function() {
        if (!_.isUndefined(this.get("subpages"))) {
            this.subpages = new App.Collection.Pages(this.get("subpages"));
        } // end if
        this.view = new App.View.Page({model: this});
    },
});

// page collection class
App.Collection.Pages = Backbone.Collection.extend({
    model: App.Model.Page
});

// single page view class
App.View.Page = Backbone.View.extend({
    tagName: "li",
    initialize: function() {
        _.bindAll(this, "render");
    },
    render: function() {
        $(this.el).html(_.template("<%=title%>", {title: this.model.get("title")}));
        return this;
    }
});

// multiple pages view class
App.View.Pages = Backbone.View.extend({
    tagName: "ul",
    initialize: function() {
        _.bindAll(this, "render");
    },
    render: function() {
        var that = this;
        this.collection.each(function(page) {
            $(that.el).append(page.view.render().el);
            if (!_.isUndefined(page.subpages)) {
                var subpagesView = new App.View.Pages({collection: page.subpages});
                $(that.el).append(subpagesView.render().el);
            } // end if
        });
        return that;
    }
});

我只是需要如此正确地指导如何正确地执行URL。我想要的想法是我可以为路由设置我的控制器,以便它可以期望任何嵌套级别的任何页面。模型,集合和嵌套集合应该能够自己生成URL,但是散列URL必须反映该级别。

理想情况下,此导航会转到以下网址:

...使用content.json数据中的“slug”的URL。这有什么意义吗?我是Backbone JS的新手,只是想做正确的事情。 谢谢,詹姆斯

2 个答案:

答案 0 :(得分:3)

这是我最喜欢的解决方案:使用PathJS

答案 1 :(得分:2)

为什么不解析slu ??

所以你可以在Backbone.Controller中有一个如下所示的路径:

'pages/:id' : showPage

然后showPage看起来像:

showPage(id) : function(id) {
   parse out the string 'services/details/etc'
   look up the slug data based on that IE pages['services']['details']['etc']
}

或者如果页面实际上需要以不同的方式处理,您可以设置多条路线,这样更精细:

'pages/:id' : showPage
'pages/:id/:nest' : showNestedPage
'pages/:id/:nest/:more' : showNestedMorePage