Backbone.js和router.navigate

时间:2014-05-28 18:00:27

标签: javascript backbone.js navigation

我试图改进我的小骨干应用程序的导航。现在我只是使用html链接进行一些简单的导航,这些链接用于href元素中的#path / to / page。

我遇到的是当我点击其中一个然后点击后退按钮,页面没有正确刷新,HTML内容没有变化。所以我试图将导航功能合并到我的代码中。

我遇到的问题是,我找不到与我目前正在使用的代码布局相匹配的示例,而且我不了解骨干的工作原理是如何适应的我发现有用的东西。

以下是我所拥有的:

app.js - 从index.html文件中调用

require.config({

    baseUrl: 'js/lib',

    paths: {
        app: '../app',
        tpl: '../tpl',
        bootstrap: 'bootstrap/js/',

    },

    shim: {
        'backbone': {
            deps: ['underscore', 'jquery'],
            exports: 'Backbone'
        },
        'underscore': {
            exports: '_'
        }
    }
});

require([
    'jquery', 
    'backbone', 
    'app/router',
], function ($, Backbone, Router) {
    var router = new Router();
    Backbone.history.start();
});

app / router.js - 在app.js中实例化

define(function (require) {

    "use strict";

    var $           = require('jquery'),
        Backbone    = require('backbone'),
        WindowView   = require('app/views/Window'),

        breadcrumbs = {"Home": ""},
        $body = "",
        $content = "",
        windowView = "";

    return Backbone.Router.extend({

        initialize: function () {
            require([], function () {
                $body = $('body');
                windowView = new WindowView({el: $body}).render();
                $content = $("#content", windowView.el);
            });
        },

        routes: {
            ''                                                : 'home',
            'profile/login(/)'                                : 'candidateProfileLogin',
            'profile/manage(/)'                               : 'candidateProfileLogin',
            'profile/manage/:id(/)'                           : 'candidateProfileHome',
            'profile/manage/:id/questionnaire/:page(/)'       : 'candidateProfileQuestionnaire',
            'profile/manage/:id/:section(/)'                  : 'candidateProfileSection',
        },

        home: function (){
        },

        candidateProfileLogin: function () {
            require(['app/views/CandidateLogin'], function (CandidateLoginView) {
                console.log(Backbone.history.fragment);
                var view = new CandidateLoginView({el: $content});
                view.render();
            });
        },

        candidateProfileHome: function (id) {
            require(["app/views/Candidate", "app/models/candidate"], function (CandidateView, models) {
                var candidate = new models.Candidate({id: id});
                candidate.fetch({
                    success: function (data) {
                        var view = new CandidateView({model: data, el: $content});
                        view.render();
                    },
                    error: function (data) {
                        var view = new CandidateView({model: data, el: $content});
                        view.render();
                    }
                });
            });
        },

        candidateProfileSection: function (id, section) {
            require(["app/views/Candidate", "app/models/candidate"], function (CandidateView, models) {

                var candidate = new models.Candidate({id: id});
                candidate.fetch({
                    success: function (data) {
                        var view = new CandidateView({model: data, el: $content});
                        view.render(section);
                    },
                    error: function (data) {
                        //Output the data to the console. Let the template take care of the error pages
                        console.log(data);
                        var view = new CandidateView({model: data, el: $content});
                        view.render();
                    }
                });
            });
        },

        candidateProfileQuestionnaire: function (id, page) {
            require(["app/views/Candidate", "app/models/candidate"], function (CandidateView, models) {
                var candidate = new models.Candidate({id: id});
                candidate.fetch({
                    success: function (data) {
                        var view = new CandidateView({model: data, el: $content});
                        view.render(page);
                    },
                    error: function (data) {
                        //Output the data to the console. Let the template take care of the error pages
                        console.log(data);
                        var view = new CandidateView({model: data, el: $content});
                        view.render();
                    }
                });
            });
        },
    });
});

app / views / Candidate.js - 我的观点我试图处理点击次数

define(function (require) {

    "use strict";

    var $                     = require('jquery'),
        _                     = require('underscore'),
        Backbone              = require('backbone'),
        tpl                   = require('text!tpl/Candidate.html'),
        template              = _.template(tpl),

        CandidateErrorView    = require('app/views/CandidateError'),
        errtpl                = require('text!tpl/CandidateError.html'),
        errTemplate           = _.template(errtpl);

    return Backbone.View.extend({

        events: {
            'submit #voters-guide-personalInfo': 'savePersonalInfo',
            'submit #voters-guide-essay'       : 'saveEssay',
            'submit #voters-guide-survey'      : 'saveSurvey',
            'submit #voters-guide-endorsements': 'saveEndorsements',
            'submit #voters-guide-photo'       : 'savePhoto',

            'click #table-of-contents a' : 'navTOC',
        },

        savePersonalInfo: function (event) {
            console.log(event);
        },

        saveEssay: function (event) {
            console.log(event);
        },

        saveSurvey: function (event) {
            console.log(event);
        },

        saveEndorsements: function (event) {
            console.log(event);
        },

        savePhoto: function(event) {
            console.log(event);
        },

        navTOC: function (event) {
            console.log(event.target);
            var id   = $(event.target).data('candidate-id');
            var path = $(event.target).data('path');
            //router.navigate("profile/manage/" + id + "/" + path, {trigger: true});
        },

        render: function (page) {
            //Check to see if we have any errors
            if (!this.model.get('error')) {
                var dataToSend = {candidate: this.model.attributes};

                switch(page) {
                    case 'personalInfo':
                        template = _.template(require('text!tpl/Candidate-personalInfo.html'));
                    break;

                    case 'essay':
                        template = _.template(require('text!tpl/Candidate-essay.html'));
                    break;

                    case 'survey':
                        template = _.template(require('text!tpl/Candidate-survey.html'));
                    break;

                    case 'endorsements':
                        template = _.template(require('text!tpl/Candidate-endorsements.html'));
                    break;

                    case 'photo':
                        template = _.template(require('text!tpl/Candidate-photo.html'));
                    break;

                    default:
                    break;
                }

                this.$el.html(template(dataToSend));
                return this;
            } else {
                this.$el.html(errTemplate({candidate: this.model.attributes}));
                return this;
            }
        }
    });
});

现在,为了阻止页面内容在我按下后退按钮时没有重新加载。问题,我一直在研究骨干可用的导航功能(这个:router.navigate(fragment, [options]);)。有很多关于如何使用它的示例,但它们似乎都没有与我使用的文件设置类似,所以我不确定从我的视图中如何最好地访问此功能。如果我在视图中包含路由器文件并实例化它的新版本,则分页符b / c它会再次尝试运行初始化函数。

我真的不知道这应该如何运作。

有人能指出我正确的方向吗?

谢谢! --Lisa

P.S。如果有人有更好的想法,我全都听见了!

1 个答案:

答案 0 :(得分:2)

您应该有权访问Backbone对象,该对象可以使用history.navigate功能进行导航。如果你打电话给trigger: true传递,你将调用该路线。例如:

Backbone.history.navigate("profile/manage", { trigger: true });