10

我正在使用 RequireJS 和 Backbone.js 开发一个移动应用程序。data-transition我想通过向每个锚点添加和属性来指定从一个页面到另一个页面的转换data-direction(与使用 jQuery Mobile 的方式相同):

<a href="#home" data-transition="slide" data-direction="left">Go to the home page</a>

我所有的视图都扩展了一个基本视图,该视图将点击处理程序附加到锚点并捕获这些属性的值:

define([
    'zepto',
    'lodash',
    'backbone'
], function ($, _, Backbone) {
    'use strict';

    BaseView = Backbone.View.extend({
        events: {
            'click a': 'navigate'
        },
        navigate: function (e) {
            e.preventDefault();

            var href = $(e.currentTarget).attr('href'),
                transition = $(e.currentTarget).attr('data-transition'),
                direction = $(e.currentTarget).attr('data-direction');

            Backbone.history.navigate(href, true);
        }
    });
});

我的问题是我不知道如何将这些值传递给我的路由器的路由处理程序,定义为另一个模块:

define([
    'zepto',
    'lodash',
    'backbone'
], function ($, _, Backbone) {
    'use strict';

    var Router = Backbone.Thumb.Router.extend({
        routes: {
            '': 'home'
        }
    });

    var initialize = function () {
        var router = new Router();

        router.on('route:home', function () {
            require(['views/home'], function (HomeView) {
                var homeView = new HomeView();

                // Get the data-transition and data-direction attributes
                // ​​of the clicked anchor here:

                // var transition = ???,
                //     direction = ???;

                router.animate(homeView.render().$el, transition, direction);
            });
        });

        Backbone.history.start();
    };

    return {
        initialize: initialize
    };
});

有谁知道解决这个问题的好方法?

非常感谢您!:-) 此致,

大卫

4

1 回答 1

23

活动

您可能知道,Backbone.js 是一个事件驱动的框架。它定义的每个对象都继承自该Backbone.Events对象,并且可以发送和接收事件消息。这意味着路由器本身可以监听事件。

使用全局消息

从 0.9.2 版本开始,Backbone全局对象本身可以用作全局消息传递的中介。由于应用程序中的视图对象可能不知道路由器(使用 requireJS 模块时尤其如此),因此可以使用Mediator启用这些对象之间的通信。

监听全局事件的路由器示例:

var router = Backbone.Router.extend({
  initialize: function() {
    this.listenTo( Backbone, 'page-transition', this.animate );
  },
  animate: function( href, transition, direction ) {
    // Do something interesting with this
  }
});

这里发生了什么?

  1. 路由器在实例化时会在堆栈中注册自己的animate函数。Backbone.events['page-transition']
  2. Backbone对象触发page-transition事件时,它将router.animate使用事件触发器提供的参数调用函数。

我在哪里触发事件?

从应用程序的任何地方

如何触发事件?

这是基于您问题中的代码的示例:

BaseView = Backbone.View.extend({
  events: {
    'click a': 'transition'
  },
  transition: function (e) {
    e.preventDefault();
    var href = $(e.currentTarget).attr('href'),
        transition = $(e.currentTarget).attr('data-transition'),
        direction = $(e.currentTarget).attr('data-direction');

    Backbone.trigger('page-transition', href, transition, direction );
  }
});

由于您的路由器已经page-transition从对象注册到事件Backbone,它将router.animate使用正确的参数调用该函数。

结论

这种模式可以在你的 Backbone 应用程序的任何地方使用,这些事件可以被任何 Backbone 扩展对象监听,可能是一个Collection, Model, View, Router... 你甚至可以用这个衬垫创建一个特殊的中介:

var mediator = _.extend({}, Backbone.Events);

这种模式非常强大,因为它促进了模块之间的完全解耦。您的模块不必知道谁在处理该功能,他们只需要知道这不是他们的责任,并通过触发事件来警告应用程序。

于 2013-07-19T21:49:47.597 回答