Przejścia stron z RequireJS i Backbone.js

Rozwijam aplikację mobilną z wykorzystaniem RequireJS i Backbone.js. Chciałbym określić przejście z jednej strony na drugą, dodając atrybuty data-transition i data-direction do każdego anchora (tak samo jak w jQuery Mobile):

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

Wszystkie moje widoki rozszerzają widok podstawowy, który dołącza obsługę kliknięć do kotwic i wychwytuje wartości tych atrybutów:

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);
        }
    });
});

Mój problem polega na tym, że nie wiem jak przekazać te wartości do routera, zdefiniowanego jako inny moduł:

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
    };
});

Czy ktoś zna dobre rozwiązanie tego problemu?

Z góry bardzo dziękuję! :- ) Pozdrawiam,

David

Author: davidg, 2013-07-14

1 answers

Wydarzenia

Jak zapewne wiesz, kręgosłup.js jest frameworkiem opartym na zdarzeniach. Każdy obiekt definiuje dziedziczenie z obiektu Backbone.Events i może wysyłać i odbierać wiadomości zdarzeń. Oznacza to, że sam router może słuchać zdarzeń.

Używanie komunikatów globalnych

Od wersji 0.9.2, sam obiekt Backbone global może być używany jako mediator do przesyłania wiadomości globalnych. Ponieważ obiekt widoku w aplikacji może nie wiedzieć o routerze (dotyczy to zwłaszcza modułów requireJS), możliwe jest włączenie komunikacji pomiędzy tymi obiektami za pomocą mediatora .

Przykład routera nasłuchującego zdarzenia globalnego:
var router = Backbone.Router.extend({
  initialize: function() {
    this.listenTo( Backbone, 'page-transition', this.animate );
  },
  animate: function( href, transition, direction ) {
    // Do something interesting with this
  }
});

Co tu się dzieje?

    Router rejestruje własną funkcję animate w stosie Backbone.events['page-transition'], gdy jest tworzona instancja.
  1. gdy obiekt Backbone wywoła zdarzenie page-transition, wywoła funkcję router.animate z argumentami dostarczonymi w zdarzeniu trigger.

Gdzie uruchomić Zdarzenie?

Z gdziekolwiek w aplikacji.

Jak uruchomić Zdarzenie?

Oto przykład oparty na kodzie z twojego pytania:
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 );
  }
});

Ponieważ twój router zarejestrował się już na zdarzenie page-transition z obiektu Backbone, wywoła funkcję router.animate z odpowiednimi argumentami.

Podsumowanie

Ten wzór może być używany wszędzie w twoim kręgosłupie aplikacji, zdarzenia te mogą być nasłuchiwane przez dowolny obiekt Rozszerzony, może to być Collection, Model, View, Router... Można nawet stworzyć specjalny mediator z tym jednym linerem: {]}

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

Ten wzór jest bardzo potężny, ponieważ sprzyja pełnemu odsprzęganiu między modułami. Twoje Moduły nie muszą wiedzieć, kto obsługuje funkcjonalność, muszą tylko wiedzieć, że nie jest to ich odpowiedzialność i ostrzec aplikację o tym, wyzwalając Zdarzenie.

 23
Author: mor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-27 15:47:12