Vaše první aplikace Backbone.js – Výběr služeb

Rámce MVC na straně klienta se staly stále populárnějšími s rostoucí složitostí webových aplikací v prohlížeči. Tyto rámce umožňují organizovat váš JavaScript pomocí osvědčeného vzoru MVC. Backbone.js je jedním z nejpopulárnějších a rychle se stává volbou při zvažování takového rámce.

Dnes vytvoříme formulář pro výběr služeb s Backbone.js, který vám umožní vybrat sadu položek ze seznamu. Pole celkové ceny bude vypočítáno v reálném čase s celkovou cenou služeb.

Co je Backbone.js?

Backbone.js je knihovna, která dává strukturu webovým aplikacím tím, že poskytuje modely, kolekce a pohledy, vše propojené s vlastními událostmi. Připojí vaši aplikaci k vašemu backendu prostřednictvím rozhraní RESTful JSON a může automaticky načítat a ukládat data. V tomto tutoriálu nebudeme používat pokročilé funkce knihovny – vše bude uloženo na straně klienta. Páteř nenahrazuje a nezávisí na jQuery, ale tyto dva spolu dobře spolupracují.

Páteř však vaše problémy zázračně nevyřeší – stále musíte být chytří ve způsobu, jakým organizujete svůj kód, což může být problém, pokud nemáte předchozí zkušenosti s frameworky MVC. Páteř může být také overkill pro menší aplikace, kde by stačilo pár řádků jQuery, takže by bylo lepší nechat na velké základny kódu. Aplikace, kterou zde budujeme, je v prvním táboře, ale ukazuje základní koncepty rámce.

HTML

Začínáme s běžným HTML5 dokumentem. Nepřidal jsem HTML5 shim, takže to nemusí vypadat dobře ve starších IE:

index.html

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8" />
        <title>Your first Backbone.js App | Tutorialzine </title>

        <!-- Google web fonts -->
        <link href="http://fonts.googleapis.com/css?family=PT+Sans:400,700" rel='stylesheet' />

        <!-- The main CSS file -->
        <link href="assets/css/style.css" rel="stylesheet" />

    </head>

    <body>

        <form id="main" method="post" action="submit.php">
            <h1>My Services</h1>

            <ul id="services">
                <!-- The services will be inserted here -->
            </ul>

            <p id="total">total: <span>$0</span></p>

            <input type="submit" id="order" value="Order" />

        </form>

        <!-- JavaScript Includes -->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
        <script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
        <script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"></script>

        <script src="assets/js/script.js"></script>

    </body>
</html>

Hlavním prvkem na stránce je formulář. UL uvnitř bude vyplněno položkami LI pro služby a rozpětí uvnitř #total odstavec bude držet cenu.

Před uzavírací značku jsem zahrnul jQuery, Backbone a knihovnu Underscore (páteř závisí na jejích výkonných obslužných funkcích). Jako poslední přichází soubor script.js, který můžete vidět v další sekci.

JavaScript

Zde je celková myšlenka našeho kódu páteře:

  1. Nejprve vytvoříme model služby. Bude mít vlastnosti pro name služby, cena a zaškrtnuto - stavové pole zobrazující, zda byla tato služba vybrána nebo ne. Objekt této třídy bude vytvořen pro každou službu, kterou nabízíme;
  2. Pak vytvoříme páteřní kolekci, která bude ukládat všechny služby. Usnadní poslech událostí na všech objektech najednou. Ve větších aplikacích byste mohli naslouchat tomu, kdy jsou položky vkládány nebo odebírány z kolekce, a podle toho aktualizovat zobrazení. V našem případě, protože položky ve sbírce jsou předurčeny, budeme pouze naslouchat změně událost (která je vyvolána vždy, když je zaškrtnuto vlastnost je aktualizována).
  3. Poté definujeme pohled pro služby. Každý pohled bude spojen s jedním modelem a převede jeho vlastnosti do HTML. Poslouchá kliknutí a aktualizuje zaškrtnuté vlastnost modelu.
  4. Nakonec definujeme hlavní pohled, který prochází všemi službami v kolekci a vytváří pro ně pohledy. Také naslouchá události změny v kolekci a aktualizuje celkovou cenu.

Protože vím, že jste nečetli vše výše uvedené, zde je bohatě komentovaný zdrojový kód:

assets/js/script.js

$(function(){

    // Create a model for the services
    var Service = Backbone.Model.extend({

        // Will contain three attributes.
        // These are their default values

        defaults:{
            title: 'My service',
            price: 100,
            checked: false
        },

        // Helper function for checking/unchecking a service
        toggle: function(){
            this.set('checked', !this.get('checked'));
        }
    });

    // Create a collection of services
    var ServiceList = Backbone.Collection.extend({

        // Will hold objects of the Service model
        model: Service,

        // Return an array only with the checked services
        getChecked: function(){
            return this.where({checked:true});
        }
    });

    // Prefill the collection with a number of services.
    var services = new ServiceList([
        new Service({ title: 'web development', price: 200}),
        new Service({ title: 'web design', price: 250}),
        new Service({ title: 'photography', price: 100}),
        new Service({ title: 'coffee drinking', price: 10})
        // Add more here
    ]);

    // This view turns a Service model into HTML. Will create LI elements.
    var ServiceView = Backbone.View.extend({
        tagName: 'li',

        events:{
            'click': 'toggleService'
        },

        initialize: function(){

            // Set up event listeners. The change backbone event
            // is raised when a property changes (like the checked field)

            this.listenTo(this.model, 'change', this.render);
        },

        render: function(){

            // Create the HTML

            this.$el.html('<input type="checkbox" value="1" name="' + this.model.get('title') + '" /> ' + this.model.get('title') + '<span>$' + this.model.get('price') + '</span>');
            this.$('input').prop('checked', this.model.get('checked'));

            // Returning the object is a good practice
            // that makes chaining possible
            return this;
        },

        toggleService: function(){
            this.model.toggle();
        }
    });

    // The main view of the application
    var App = Backbone.View.extend({

        // Base the view on an existing element
        el: $('#main'),

        initialize: function(){

            // Cache these selectors
            this.total = $('#total span');
            this.list = $('#services');

            // Listen for the change event on the collection.
            // This is equivalent to listening on every one of the 
            // service objects in the collection.
            this.listenTo(services, 'change', this.render);

            // Create views for every one of the services in the
            // collection and add them to the page

            services.each(function(service){

                var view = new ServiceView({ model: service });
                this.list.append(view.render().el);

            }, this);   // "this" is the context in the callback
        },

        render: function(){

            // Calculate the total order amount by agregating
            // the prices of only the checked elements

            var total = 0;

            _.each(services.getChecked(), function(elem){
                total += elem.get('price');
            });

            // Update the total price
            this.total.text('$'+total);

            return this;
        }
    });

    new App();

});

Jak vidíte, musíte rozšířit třídy poskytované Backbone a v tomto procesu přepsat metody, které chcete provádět jinak (u pohledů téměř jistě chcete přepsat metodu vykreslování). Můžete je dále rozšiřovat a vytvářet hierarchie tříd.

Pohledy mohou buď vytvářet vlastní HTML, jako v případě ServiceView nebo být připojen ke stávajícím prvkům. Hlavní zobrazení aplikace je Aplikace , který je vázán na #main formulář. Inicializuje ostatní pohledy a aktualizuje celkovou cenu ve své renderovací metodě.

PHP

Zahrnul jsem také řadu PHP, která zpracuje odesílání formulářů. Vše, co dělá, je tisk názvů vybraných polí zaškrtávacích polí:

odeslat.php

echo htmlspecialchars(implode(array_keys($_POST), ', '));

Můžete jej rozšířit o jakoukoli funkci, kterou potřebujete, jako je odesílání e-mailů, vkládání výsledků do databáze a další.

Máme hotovo!

Tímto je náš formulář pro výběr páteřní služby hotový! Doufám, že pro vás bude formulář užitečný a že vám poskytne dobrý přehled o frameworku, takže budete vědět, kdy je ten správný čas jej použít.

Zdroje a další čtení:

  • Dokumentace páteřní sítě
  • Dokumentace podtržení
  • Aplikace se seznamem úkolů s páteří
  • Bezplatná kniha Základy páteře
  • Seznam výukových programů a příkladů páteře

No