Статьи

Руководство по BackBone — Часть 7. Понимание маршрутов и истории Backbone.js

В этой статье мы попытаемся взглянуть на маршруты в Backbone.js. Мы попытаемся понять, как маршруты могут быть полезны в крупномасштабных одностраничных приложениях и как мы можем использовать маршруты для выполнения действий на основе запрошенного URL.

Фон

Мы используем веб-приложение уже более двух десятилетий. Это заставило нас настроиться на некоторые функции, которые предоставляют веб-сайты. Одна из таких функций — возможность копировать URL-адрес и использовать его для просмотра той области приложения, которую мы просматривали ранее. Другим примером является использование кнопок навигации в браузере для навигации по страницам.

Когда мы создаем одностраничные приложения, на экране отображается только одна страница. Для каждой страницы нет отдельного URL. Браузер не загружает отдельные страницы для отдельных экранов. Так как же мы можем выполнять вышеупомянутые операции даже с одностраничным приложением? Ответ — магистральные маршруты.

Ссылка на полную серию:

  1. BackBone Tutorial — Часть 1. Введение в Backbone.Js [ ^ ]
  2. Руководство по BackBone — часть 2: Понимание основ моделей Backbone [ ^ ]
  3. Руководство по BackBone — часть 3: подробнее о моделях Backbone [ ^ ]
  4. BackBone Tutorial — Часть 4. Операции CRUD на моделях BackboneJs, использующих службу HTTP REST [ ^ ]
  5. Руководство по BackBone — часть 5: Понимание коллекций Backbone.js [ ^ ]
  6. Руководство по BackBone — часть 6: Понимание представлений Backbone.js [ ^ ]
  7. BackBone Tutorial — Часть 7. Понимание маршрутов и истории Backbone.js [ ^ ]

Используя код

Магистральные маршруты и история предоставляют нам механизм, с помощью которого мы можем копировать URL-адреса и использовать их для получения точного представления. Это также позволяет нам использовать браузерную навигацию с одностраничными приложениями. На самом деле маршруты облегчают возможность иметь глубоко скопированные URL-адреса, а история предоставляет возможность использования навигации в браузере.

Жизнь без роутера

Давайте попробуем создать простое приложение, которое не использует маршрутизатор. Давайте создадим три простых представления, и эти представления будут отображаться в одной области нашего приложения на основе выбора пользователя. Давайте создадим 3 очень простых представления.

var View1 = Backbone.View.extend({
  
    initialize: function() {
        this.render();
    },
 
    render: function() {
        this.$el.html(this.model.get('Message') + " from the View 1");
        return this;
    }
});
 
var View2 = Backbone.View.extend({
  
    initialize: function() {
        this.render();
    },
 
    render: function() {
        this.$el.html(this.model.get('Message') + " from the View 2");
        return this;
    }
});
 
var View3 = Backbone.View.extend({
    
    initialize: function() {
        this.render();
    },
 
    render: function() {
        this.$el.html(this.model.get('Message') + " from the View 3");
        return this;
    }
});

Теперь нам нужно представление, которое будет содержать представление и отображать его всякий раз, когда пользователь делает выбор на экране.

var ContainerView = Backbone.View.extend({ myChildView: null, render: function() { this.$el.html("Greeting Area"); this.$el.append(this.myChildView.$el); return this; } });
var ContainerView = Backbone.View.extend({
     myChildView: null,
    
     render: function() {
        this.$el.html("Greeting Area");
 
        this.$el.append(this.myChildView.$el);
        return this;
    }
});

Теперь нам нужно представление, которое будет содержать представление и отображать его всякий раз, когда пользователь делает выбор на экране.

Теперь давайте создадим простой div на пользовательском интерфейсе, который будет использоваться как elto в этом ContainerView. Затем мы разместим три кнопки на пользовательском интерфейсе, которые позволят пользователю изменять вид. Ниже приведен код приложения, в котором создается представление контейнера, и функции, которые будут вызываться, когда пользователь выбирает представление на экране.

var greeting = new GreetModel({ Message: "Hello world" });
 
var container = new ContainerView({ el: $("#AppContainer"), model: greeting });
var view1 = null;
var view2 = null;
var view3 = null;
 
function showView1() {
    if (view1 == null) {
        view1 = new View1({ model: greeting });
    }
 
    container.myChildView = view1;
    container.render();
}
 
function showView2() {
    if (view2 == null) {
        view2 = new View2({ model: greeting });
    }
 
    container.myChildView = view2;
    container.render();
}
 
function showView3() {
    if (view3 == null) {
        view3 = new View3({ model: greeting });
    }
 
    container.myChildView = view3;
    container.render();
}

Теперь давайте запустим приложение и посмотрим результаты.

nonrouter

Когда мы нажимаем на кнопки, мы видим, что фактическое представление получает изменения, но URL не получает изменений. Это будет означать, что нет никакого способа, я могу скопировать URL-адрес и перейти непосредственно к любому представлению. Кроме того, вторая вещь, на которую следует обратить внимание, это то, что если мы нажмем кнопку «Назад» в браузере, приложение исчезнет (поскольку оно все еще находится на одной странице с точки зрения браузера).

Примечание. Загрузите и запустите образец кода, чтобы увидеть это в действии.

Привет магистральные маршруты

Теперь вышеупомянутая проблема может быть легко решена с использованием магистральных маршрутов и истории. Итак, давайте попробуем сначала посмотреть, что такое магистральные маршруты.

Магистральные маршруты — это простые объекты, которые обрабатывают входящее значение маршрута из URL и вызывают любую функцию. Давайте создадим очень простой класс маршрута для нашего приложения.

var myRouter = Backbone.Router.extend({
});

В нашем классе маршрутов нам нужно будет определить маршруты, которые будет поддерживать наше приложение, и способы их обработки. Итак, сначала давайте создадим простой маршрут, где присутствует только URL. Обычно это стартовая страница нашего приложения. Для нашего приложения давайте просто откроем view1, когда на маршруте ничего нет. Затем, если запрос относится к какому-либо конкретному представлению, мы просто вызовем функцию, которая позаботится о предоставлении соответствующего представления.

var myRouter = Backbone.Router.extend({
    
    greeting: null,
    container: null,
    view1: null,
    view2: null,
    view3: null,
    
    initialize: function() {
        this.greeting = new GreetModel({ Message: "Hello world" });
        this.container = new ContainerView({ el: $("#rAppContainer"), model: this.greeting });
    },

    routes: {
        "": "handleRoute1",
        "view1": "handleRoute1",
        "view2": "handleRoute2",
        "view3": "handleRoute3"
    },

    handleRoute1: function () {
        if (this.view1 == null) {
            this.view1 = new View1({ model: this.greeting });
        }

        this.container.myChildView = this.view1;
        this.container.render();
    },

    handleRoute2: function () {
        if (this.view2 == null) {
            this.view2 = new View2({ model: this.greeting });
        }

        this.container.myChildView = this.view2;
        this.container.render();
    },

    handleRoute3: function () {
        if (this.view3 == null) {
            this.view3 = new View3({ model: this.greeting });
        }

        this.container.myChildView = this.view3;
        this.container.render();
    }
});

Теперь этот класс маршрута содержит полную логику обработки URL-запросов и соответствующей визуализации представления. Не только это, мы можем видеть, что код, который был написан в глобальной области видимости ранее, т.е. контроллер и представление создания, все, что помещено в маршрут сейчас. Это также означало бы, что маршруты не только предоставляют нам глубоко копируемые URL-адреса, но также могут предоставить больше возможностей для более структурированного кода (поскольку у нас может быть несколько классов маршрутов, и каждый класс маршрутов может обрабатывать все соответствующие представления для определенных маршрутов).

История BackBone и создание маршрутов

Backbone history — это глобальный маршрутизатор, который будет отслеживать историю и позволит нам включить маршрутизацию в приложении. Чтобы создать маршрут и начать отслеживать историю навигации, нам нужно просто создать класс маршрутизатора и вызвать Backbone.history.start, чтобы магистраль начала прослушивать маршруты и управлять историей.

$(document).ready(function () {
    router = new myRouter();
    Backbone.history.start();
})

Вызов и запрос маршрутов

Маршрут может быть вызван из других частей приложения или просто запрошен пользователем.

  1. Вызов маршрута: приложение хочет перейти к определенному маршруту (это можно сделать, перейдя к маршруту, вызвав функцию навигации: router.navigate (‘view1’);
  2. Запрос маршрута: пользователь вводит полный URL-адрес (это будет работать без проблем)

Давайте запустим приложение и посмотрим результат.

withRoutes

Передача параметров в Маршрутах

Мы также можем передать параметры в маршрут. Давайте попробуем создать новый маршрут, где пользователь будет запрашивать представление параметризованным способом. Параметры могут быть определены как «route /: param»

var myRouter = Backbone.Router.extend({

    greeting: null,
    container: null,
    view1: null,
    view2: null,
    view3: null,

    initialize: function () {
        this.greeting = new GreetModel({ Message: "Hello world" });
        this.container = new ContainerView({ el: $("#rAppContainer"), model: this.greeting });
    },

    routes: {
        "": "handleRoute1",
        "view/:viewid": "handleRouteAll"
    },

     handleRouteAll: function (viewid) {

        if (viewid == 1) {
            this.handleRoute1();
        }
        else if (viewid == 2) {
            this.handleRoute2();
        }
        else if (viewid == 3) {
            this.handleRoute3();
        }
    },

    handleRoute1: function () {
        if (this.view1 == null) {
            this.view1 = new View1({ model: this.greeting });
        }

        this.container.myChildView = this.view1;
        this.container.render();
    },

    handleRoute2: function () {
        if (this.view2 == null) {
            this.view2 = new View2({ model: this.greeting });
        }

        this.container.myChildView = this.view2;
        this.container.render();
    },

    handleRoute3: function () {
        if (this.view3 == null) {
            this.view3 = new View3({ model: this.greeting });
        }

        this.container.myChildView = this.view3;
        this.container.render();
    }   
});

Вышеупомянутый маршрут может быть вызван путем передачи view / 2 в качестве URL. viewId, переданный маршрутизатору, будет 2.

customOptional

Наличие необязательных параметров в маршрутах

Мы также можем передавать необязательные параметры в маршруты. Давайте попробуем передать простой параметр в определенном выше маршруте и посмотреть, как он работает. дополнительные параметры могут быть определены как «route (/: param)».

var myRouter = Backbone.Router.extend({

    routes: {
        "": "handleRoute1",
        "view1": "handleRoute1",
        "view2": "handleRoute2",
        "view3": "handleRoute3",
        "view/:viewid(/:msg)": "handleRouteAll"
    },

    handleRouteAll: function (viewid, msg) {

        if (msg) {
            alert(msg);
        }
    }
});

В приведенном выше коде, если мы передадим второй параметр, т.е. view / 2 / test, предупреждение будет показано иначе.

customOptional

Примечание. Определение маршрута также может содержать сложные шаблоны на основе регулярных выражений, если нам нужен один маршрут для обработки нескольких URL-адресов на основе некоторого регулярного выражения.

Достопримечательность

В этой статье мы увидели маршруты backbone.js. Мы увидели, как маршруты позволяют нам создавать закладки для URL и позволяют пользователю запрашивать представление на основе URL. Мы также рассмотрели, как мы можем использовать навигацию в браузере, используя историю магистрали. Это было написано с точки зрения начинающего. Я надеюсь, что это было информативно.

Загрузить пример кода для этой статьи:  backboneRoutesSample