Advertisement
  1. Code
  2. JavaScript
  3. jQuery

Satu Page ToDo aplikasi dengan Backbone.js

Scroll to top
Read Time: 18 min

() translation by (you can also view the original English article)

Backbone.js adalah kerangka kerja JavaScript untuk membangun aplikasi web yang fleksibel. Itu datang dengan model, koleksi, pemandangan, peristiwa, Router dan beberapa fitur besar lainnya. Pada artikel ini kami akan mengembangkan aplikasi ToDo sederhana yang mendukung menambahkan, mengedit, dan menghapus tugas. Kita juga harus mampu menandai tugas sebagai selesai dan arsip itu. Untuk menjaga panjang posting ini masuk akal, kita tidak akan menyertakan komunikasi dengan database. Semua data akan disimpan di sisi klien.

Setup

Berikut adalah struktur file yang kita akan menggunakan:

1
css
2
    └── styles.css
3
js
4
    └── collections
5
        └── ToDos.js
6
    └── models
7
        └── ToDo.js
8
    └── vendor
9
       └── backbone.js
10
       └── jquery-1.10.2.min.js
11
       └── underscore.js
12
    └── views
13
    └── App.js
14
 └── index.html

Ada beberapa hal yang jelas, seperti /css/styles.css dan /index.html. Mereka mengandung gaya CSS dan HTML markup. Dalam konteks Backbone.js, model adalah tempat dimana kita memelihara data kami. Jadi, ToDos kami hanya akan model. Dan karena kita akan memiliki lebih dari satu tugas, kami akan mengatur mereka ke dalam koleksi. Logika bisnis didistribusikan antara pandangan dan file aplikasi utama, App.js. Backbone.js memiliki ketergantungan sulit hanya satu - Underscore.js. Kerangka kerja juga bermain sangat baik dengan jQuery, jadi mereka berdua pergi ke direktori vendor. Yang kami butuhkan sekarang adalah hanya sedikit HTML markup dan kami siap untuk pergi.

1
<!doctype html>
2
<html>
3
  <head>
4
        <title>My TODOs</title>
5
        <link rel="stylesheet" type="text/css" href="css/styles.css" />
6
    </head>
7
    <body>
8
        <div class="container">
9
            <div id="menu" class="menu cf"></div>
10
            <h1></h1>
11
            <div id="content"></div>
12
        </div>
13
        <script src="js/vendor/jquery-1.10.2.min.js"></script>
14
        <script src="js/vendor/underscore.js"></script>
15
        <script src="js/vendor/backbone.js"></script>
16
        <script src="js/App.js"></script>
17
        <script src="js/models/ToDo.js"></script>
18
        <script src="js/collections/ToDos.js"></script>
19
        <script>
20
            window.onload = function() {
21
                // bootstrap

22
            }
23
        </script>
24
    </body>
25
</html>

Seperti yang Anda lihat, kami sudah termasuk semua JavaScript file eksternal ke arah bawah, karena letaknya yang praktik yang baik untuk melakukan ini pada akhir tag badan. Kami juga mempersiapkan bootstrap aplikasi. Ada wadah untuk konten, menu, dan judul. Navigasi adalah unsur statis dan kita tidak akan mengubahnya. Kami akan mengganti konten judul dan div di bawah ini.

Perencanaan aplikasi

Hal ini selalu baik untuk memiliki rencana sebelum kita mulai bekerja pada sesuatu. Backbone.js tidak memiliki arsitektur super ketat, yang kita harus mengikuti. Itu adalah salah satu manfaat kerangka. Jadi, sebelum kita mulai dengan pelaksanaan logika bisnis, mari kita bicara tentang dasar.

Namespacing

Praktek yang baik adalah untuk menempatkan kode Anda ke lingkup sendiri. Mendaftar variabel global atau fungsi bukanlah ide yang baik. Apa yang kita akan menciptakan adalah salah satu model, satu koleksi, router dan beberapa pemandangan Backbone.js. Semua elemen harus hidup dalam ruang pribadi. App.js akan berisi kelas yang memegang semuanya.

1
// App.js

2
var app = (function() {
3
4
    var api = {
5
        views: {},
6
        models: {},
7
        collections: {},
8
        content: null,
9
        router: null,
10
        todos: null,
11
        init: function() {
12
            this.content = $("#content");
13
        },
14
        changeContent: function(el) {
15
            this.content.empty().append(el);
16
            return this;
17
        },
18
        title: function(str) {
19
            $("h1").text(str);
20
            return this;
21
        }
22
    };
23
    var ViewsFactory = {};
24
    var Router = Backbone.Router.extend({});
25
    api.router = new Router();
26
27
    return api;
28
29
})();

Di atas adalah implementasi pola modul mengungkapkan yang khas. Variabel api adalah objek yang dikembalikan dan mewakili Umum metode kelas. Pemandangan, model, dan koleksi properti akan bertindak sebagai pemegang kelas dikembalikan oleh Backbone.js. Konten adalah elemen jQuery menunjuk ke wadah antarmuka pengguna utama. Ada dua metode penolong di sini. Yang pertama update wadah itu. Kedua menetapkan judul halaman. Kemudian kita mendefinisikan sebuah modul yang disebut ViewsFactory. Hal ini akan memberikan pandangan kami dan di akhir, kami membuat router.

Anda mungkin bertanya, mengapa kita perlu sebuah pabrik untuk pandangan? Well, ada beberapa pola umum ketika bekerja dengan Backbone.js. Salah satunya adalah berhubungan dengan penciptaan dan penggunaan pandangan.

1
var ViewClass = Backbone.View.extend({ /* logic here */ });
2
var view = new ViewClass();

Hal ini baik untuk menginisialisasi pandangan hanya sekali dan meninggalkan mereka hidup. Setelah data yang berubah, kita biasanya memanggil metode pandangan dan memperbarui konten el objek. Pendekatan sangat populer lain, adalah untuk menciptakan seluruh tampilan atau mengganti semua elemen DOM. Namun, itu tidak benar-benar baik dari sudut pandang kinerja. Jadi, kita biasanya berakhir dengan kelas utilitas yang menciptakan satu contoh dari pandangan dan kembali ketika kita membutuhkannya.

Definisi komponen

Kami memiliki sebuah namespace, jadi sekarang kita dapat mulai membuat komponen. Berikut adalah tampilan menu utama:

1
// views/menu.js

2
app.views.menu = Backbone.View.extend({
3
    initialize: function() {},
4
    render: function() {}
5
});

Kami menciptakan sebuah properti yang disebut menu yang memegang kelas navigasi. Kemudian, kita dapat menambahkan metode dalam modul pabrik yang membuat instance itu.

1
var ViewsFactory = {
2
    menu: function() {
3
        if(!this.menuView) {
4
            this.menuView = new api.views.menu({ 
5
                el: $("#menu")
6
            });
7
        }
8
        return this.menuView;
9
    }
10
};

Di atas adalah bagaimana kita akan menangani semua pandangan, dan akan memastikan bahwa kita mendapatkan hanya satu dan contoh yang sama. Teknik ini bekerja dengan baik, dalam kebanyakan kasus.

Aliran

Entry point App adalah App.js dan metode init. Ini adalah apa yang akan kita sebut di handler onload objek jendela.

1
window.onload = function() {
2
    app.init();
3
}

Setelah itu, router didefinisikan mengambil kendali. Berdasarkan URL, itu memutuskan mana penangan untuk mengeksekusi. Dalam Backbone.js, kita tidak memiliki arsitektur Model-View-Controller yang biasa. Controller hilang dan sebagian besar logika dimasukkan ke dalam pandangan. Jadi, bukannya, kami kawat model langsung ke metode, dalam pandangan dan mendapatkan pembaruan instan dari antarmuka pengguna, setelah data telah berubah.

Mengelola Data

Hal yang paling penting dalam proyek kecil kami adalah data. Tugas kami adalah apa kita harus mengelola, jadi mari kita mulai dari sana. Berikut ini adalah definisi model kami.

1
// models/ToDo.js

2
app.models.ToDo = Backbone.Model.extend({
3
    defaults: {
4
        title: "ToDo",
5
        archived: false,
6
        done: false
7
    }
8
});

Hanya tiga bidang. Yang pertama berisi teks tugas dan dua lainnya adalah bendera yang menentukan status catatan.

Setiap hal di dalam kerangka kerja yang benar-benar operator acara. Dan karena model berubah dengan setter, kerangka tahu ketika data diperbarui dan dapat memberitahukan sisa sistem untuk itu. Setelah Anda mengikat sesuatu untuk pemberitahuan ini, aplikasi Anda akan bereaksi pada perubahan dalam model. Ini adalah fitur yang benar-benar kuat di Backbone.js.

Seperti saya katakan di awal, kita akan memiliki banyak catatan dan kami akan mengatur mereka menjadi sebuah koleksi yang disebut ToDos.

1
// collections/ToDos.js

2
app.collections.ToDos = Backbone.Collection.extend({
3
    initialize: function(){
4
        this.add({ title: "Learn JavaScript basics" });
5
        this.add({ title: "Go to backbonejs.org" });
6
        this.add({ title: "Develop a Backbone application" });
7
    },
8
    model: app.models.ToDo
9
    up: function(index) {
10
        if(index > 0) {
11
            var tmp = this.models[index-1];
12
            this.models[index-1] = this.models[index];
13
            this.models[index] = tmp;
14
            this.trigger("change");
15
        }
16
    },
17
    down: function(index) {
18
        if(index < this.models.length-1) {
19
            var tmp = this.models[index+1];
20
            this.models[index+1] = this.models[index];
21
            this.models[index] = tmp;
22
            this.trigger("change");
23
        }
24
    },
25
    archive: function(archived, index) {
26
        this.models[index].set("archived", archived);
27
    },
28
    changeStatus: function(done, index) {
29
        this.models[index].set("done", done);
30
    }
31
});

Metode inisialisasi adalah titik masuk koleksi. Dalam kasus kami, kami menambahkan beberapa tugas secara default. Tentu saja di dunia nyata, informasi akan datang dari database atau di tempat lain. Tetapi untuk membuat Anda fokus, kita akan melakukannya secara manual. Hal lain yang khas untuk koleksi, adalah pengaturan properti model. Ia memberitahu kelas apa jenis data yang akan disimpan. Sisa metode menerapkan logika kustom, berkaitan dengan fitur-fitur dalam aplikasi kita. atas dan bawah fungsi mengubah urutan ToDos. Untuk menyederhanakan hal-hal, kita akan mengidentifikasi setiap ToDo dengan hanya indeks dalam koleksi 's array. Ini berarti bahwa jika kita ingin mengambil satu record tertentu, kita harus menunjukkan indeks. Jadi, pemesanan hanya adalah beralih elemen dalam array. Seperti yang Anda bisa menebak dari kode di atas, this.models adalah array yang sedang kita bicarakan. Arsip dan changeStatus mengatur properti dari elemen tertentu. Kami menempatkan metode ini di sini, karena pandangan akan memiliki akses ke koleksi ToDos dan tidak untuk tugas-tugas langsung.

Selain itu, kita tidak perlu untuk membuat setiap model dari kelas app.models.ToDo, tetapi kita perlu membuat sebuah instance dari kumpulan app.collections.ToDos.

1
// App.js

2
init: function() {
3
    this.content = $("#content");
4
    this.todos = new api.collections.ToDos();
5
    return this;
6
}

Menampilkan pandangan pertama kami (navigasi utama)

Hal pertama yang kita harus menunjukkan, adalah aplikasi utama navigasi.

1
// views/menu.js

2
app.views.menu = Backbone.View.extend({
3
    template: _.template($("#tpl-menu").html()),
4
    initialize: function() {
5
        this.render();
6
    },
7
    render: function(){
8
        this.$el.html(this.template({}));
9
    }
10
});

Itu hanya sembilan baris kode, tapi banyak hal keren yang terjadi di sini. Yang pertama adalah pengaturan template. Jika Anda ingat, kami menambahkan Underscore.js App kami? Kita akan menggunakan mesin template, karena bekerja baik dan cukup sederhana untuk menggunakan.

1
_.template(templateString, [data], [settings])

Apa yang Anda miliki pada akhir, adalah fungsi yang menerima sebuah objek yang memegang informasi Anda dalam pasangan key-value dan templateString adalah HTML markup. OK, jadi ini menerima string HTML, tapi apa $("#tpl-menu").html() lakukan di sana? Ketika kita sedang mengembangkan sebuah aplikasi kecil satu halaman, kita biasanya menempatkan template langsung ke halaman seperti ini:

1
// index.html
2
<script type="text/template" id="tpl-menu">
3
    <ul>
4
        <li><a href="#">List</a></li>
5
        <li><a href="#archive">Archive</a></li>
6
        <li class="right"><a href="#new">+</a></li>
7
    </ul>

8
</script>

Dan karena script tag, tidak ditampilkan ke pengguna. Dari sudut pandangan yang lain, itu adalah sah DOM node sehingga kami bisa mendapatkan isinya dengan jQuery. Jadi, cuplikan di atas hanya mengambil isi dari tag script itu.

Metode render benar-benar penting dalam Backbone.js. Itulah fungsi yang menampilkan data. Biasanya Anda mengikat peristiwa dipecat oleh model langsung ke metode. Namun, untuk menu utama, kita tidak perlu perilaku seperti itu.

1
this.$el.html(this.template({}));

ini. $el adalah sebuah objek yang dibuat oleh kerangka dan lihat setiap memiliki secara default (ada $ infront el karena kita memiliki jQuery termasuk). Dan secara default, itu kosong<div></div>. Tentu saja Anda dapat mengubah bahwa dengan menggunakan properti tagName. Tapi apa yang lebih penting di sini, adalah bahwa kami tidak menentukan nilai untuk objek yang langsung. Kami tidak berubah itu, kita mengubah hanya isinya. Ada perbedaan besar antara baris di atas dan yang satu ini berikutnya:

1
this.$el = $(this.template({}));

Intinya adalah, bahwa jika Anda ingin melihat perubahan dalam browser Anda harus memanggil metode render sebelumnya, untuk menambahkan tampilan ke DOM. Sebaliknya hanya div kosong akan dilampirkan. Ada juga skenario lain di mana Anda memiliki pemandangan yang bersarang. Dan karena Anda mengubah properti secara langsung, komponen orangtua tidak diperbarui. Peristiwa terikat juga mungkin rusak dan Anda perlu untuk melampirkan pendengar lagi. Jadi, Anda benar-benar harus hanya mengubah konten ini. $el dan tidak nilai properti.

Tampilan sekarang siap dan kita perlu untuk menginisialisasi itu. Mari kita tambahkan ke modul pabrik kami:

1
// App.js

2
var ViewsFactory = {
3
    menu: function() {
4
        if(!this.menuView) {
5
            this.menuView = new api.views.menu({ 
6
                el: $("#menu")
7
            });
8
        }
9
        return this.menuView;
10
    }
11
};

Pada akhir cukup memanggil metode menu di daerah bootstrapping:

1
// App.js

2
init: function() {
3
    this.content = $("#content");
4
    this.todos = new api.collections.ToDos();
5
    ViewsFactory.menu();
6
    return this;
7
}

Perhatikan bahwa sementara kita membuat sebuah instance baru dari navigasi di kelas, kita mengirimkan DOM sudah ada elemen $("#menu"). Jadi, ini. $el properti di dalam pandangan sebenarnya menunjuk ke $("#menu").

Menambahkan rute

Backbone.js mendukung operasi negara mendorong. Dengan kata lain, Anda dapat memanipulasi URL browser saat ini dan perjalanan antara halaman. Namun, kami akan tetap dengan baik tua hash mengetik URL, misalnya #edit/3.

1
// App.js

2
var Router = Backbone.Router.extend({
3
    routes: {
4
        "archive": "archive",
5
        "new": "newToDo",
6
        "edit/:index": "editToDo",
7
        "delete/:index": "delteToDo",
8
        "": "list"
9
    },
10
    list: function(archive) {},
11
    archive: function() {},
12
    newToDo: function() {},
13
    editToDo: function(index) {},
14
    delteToDo: function(index) {}
15
});

Di atas adalah router kami. Ada lima rute didefinisikan dalam objek hash. Kuncinya adalah apa yang akan Anda mengetik di bilah alamat peramban dan nilai adalah fungsi yang akan dipanggil. Perhatikan bahwa ada: indeks pada dua rute. Itulah sintaks yang perlu Anda gunakan jika Anda ingin mendukung URL dinamis. Dalam kasus kami, jika Anda mengetik #edit/3 editToDo akan dijalankan dengan parameter index = 3. Baris terakhir berisi string kosong yang berarti bahwa menangani halaman rumah dari aplikasi kita.

Menampilkan daftar semua tugas-tugas

Sejauh apa yang telah kita bangun adalah tampilan utama untuk proyek kami. Ini akan mengambil data dari koleksi dan mencetaknya di layar. Kita bisa menggunakan pandangan yang sama untuk dua hal - menampilkan semua ToDos aktif dan menampilkan yang diarsipkan.

Sebelum melanjutkan pelaksanaan tampilan daftar, mari kita lihat bagaimana itu benar-benar diinisialisasi.

1
// in App.js views factory

2
list: function() {
3
    if(!this.listView) {
4
        this.listView = new api.views.list({
5
            model: api.todos
6
        });
7
    }   
8
    return this.listView;
9
}

Perhatikan bahwa kita mengirimkan dalam koleksi. Ini penting karena kita kemudian akan menggunakan this.model untuk mengakses data yang disimpan. Pabrik kembali tampilan daftar kami, tapi router adalah orang yang harus menambahkannya ke halaman.

1
// in App.js's router

2
list: function(archive) {
3
    var view = ViewsFactory.list();
4
    api
5
    .title(archive ? "Archive:" : "Your ToDos:")
6
    .changeContent(view.$el);
7
    view.setMode(archive ? "archive" : null).render();
8
}

Untuk sekarang, daftar metode di router disebut tanpa parameter. Sehingga pandangan tidak dalam modus arsip, ia akan menampilkan hanya ToDos aktif.

1
// views/list.js

2
app.views.list = Backbone.View.extend({
3
    mode: null,
4
    events: {},
5
    initialize: function() {
6
        var handler = _.bind(this.render, this);
7
        this.model.bind('change', handler);
8
        this.model.bind('add', handler);
9
        this.model.bind('remove', handler);
10
    },
11
    render: function() {},
12
    priorityUp: function(e) {},
13
    priorityDown: function(e) {},
14
    archive: function(e) {},
15
    changeStatus: function(e) {},
16
    setMode: function(mode) {
17
        this.mode = mode;
18
        return this;
19
    }
20
});

Modus properti akan digunakan selama rendering. Jika nilainya adalah mode = "Arsip" kemudian hanya ToDos diarsipkan akan ditampilkan. Peristiwa-peristiwa adalah sebuah objek yang kita akan mengisi segera. Itulah tempat dimana kita menempatkan peristiwa DOM pemetaan. Sisanya dari metode adalah tanggapan dari interaksi pengguna dan mereka secara langsung terkait dengan fitur yang dibutuhkan. Sebagai contoh, priorityUp dan priorityDown perubahan Pemesanan ToDos. Arsip bergerak item ke daerah Arsip. changeStatus hanya menandai ToDo seperti yang dilakukan.

Hal ini menarik apa yang terjadi dalam metode inisialisasi. Sebelumnya kita mengatakan bahwa biasanya Anda akan mengikat perubahan dalam model (koleksi dalam kasus kami) metode render View. Anda dapat mengetikkan this.model.bind ('Ubah', this.render). Tetapi segera Anda akan melihat bahwa kata kunci ini, dalam metode render akan tidak menunjuk ke tampilan sendiri. Itu karena cakupan berubah. Sebagai workaround, kami menciptakan sebuah pengendali dengan lingkup yang sudah didefinisikan. Itulah fungsi mengikat menekankan apa yang digunakan untuk.

Dan di sini adalah penerapan metode render.

1
// views/list.js

2
render: function() {)
3
    var html = '<ul class="list">', 
4
        self = this;
5
    this.model.each(function(todo, index) {
6
        if(self.mode === "archive" ? todo.get("archived") === true : todo.get("archived") === false) {
7
            var template = _.template($("#tpl-list-item").html());
8
            html += template({ 
9
                title: todo.get("title"),
10
                index: index,
11
                archiveLink: self.mode === "archive" ? "unarchive" : "archive",
12
                done: todo.get("done") ? "yes" : "no",
13
                doneChecked: todo.get("done")  ? 'checked=="checked"' : ""
14
            });
15
        }
16
    });
17
    html += '</ul>';
18
    this.$el.html(html);
19
    this.delegateEvents();
20
    return this;
21
}

Kami perulangan melalui semua model dalam koleksi dan menghasilkan HTML string, yang kemudian dimasukkan ke dalam tampilan 's DOM elemen. Ada beberapa pemeriksaan yang membedakan ToDos dari Diarsipkan untuk aktif. Tugas ditandai sebagai dilakukan dengan bantuan sebuah kotak centang. Jadi, untuk menunjukkan ini kita harus lulus w == dicentang "dicentang" atribut untuk elemen. Anda mungkin menyadari bahwa kita menggunakan this.delegateEvents(). Dalam kasus kami ini penting, karena kita melepaskan dan melampirkan tampilan dari DOM. Ya, kami tidak menggantikan unsur utama, tetapi penangan peristiwa yang akan dihapus. Itulah mengapa kami harus memberitahukan kepada Backbone.js untuk melampirkannya lagi. Template yang digunakan dalam kode di atas adalah:

1
// index.html
2
<script type="text/template" id="tpl-list-item">
3
    <li class="cf done-<%= done %>" data-index="<%= index %>">
4
        <h2>
5
            <input type="checkbox" data-status <%= doneChecked %> />

6
            <a href="javascript:void(0);" data-up>&#8593;</a>

7
            <a href="javascript:void(0);" data-down>&#8595;</a>

8
            <%= title %>
9
        </h2>

10
        <div class="options">
11
            <a href="#edit/<%= index %>">edit</a>

12
            <a href="javascript:void(0);" data-archive><%= archiveLink %></a>

13
            <a href="#delete/<%= index %>">delete</a>

14
        </div>

15
    </li>

16
</script>

Perhatikan bahwa ada kelas CSS yang didefinisikan disebut dilakukan-ya, yang cat ToDo dengan latar hijau. Selain itu, ada banyak link yang akan kita gunakan untuk mengimplementasikan fungsi yang diperlukan. Mereka semua memiliki data atribut. Utama node elemen, li, memiliki data-indeks. Nilai atribut ini menunjukkan indeks tugas dalam koleksi. Pemberitahuan bahwa ekspresi khusus terbungkus < % =... %> dikirim ke fungsi template. Ini adalah data yang disuntikkan ke dalam template.

Saatnya untuk menambahkan beberapa peristiwa ke tampilan.

1
// views/list.js

2
events: {
3
    'click a[data-up]': 'priorityUp',
4
    'click a[data-down]': 'priorityDown',
5
    'click a[data-archive]': 'archive',
6
    'click input[data-status]': 'changeStatus'
7
}

Dalam Backbone.js acara definisi adalah hanya hash. Anda pertama ketik nama acara dan kemudian pemilih. Nilai-nilai properti adalah benar-benar metode tampilan.

1
// views/list.js

2
priorityUp: function(e) {
3
    var index = parseInt(e.target.parentNode.parentNode.getAttribute("data-index"));
4
    this.model.up(index);
5
},
6
priorityDown: function(e) {
7
    var index = parseInt(e.target.parentNode.parentNode.getAttribute("data-index"));
8
    this.model.down(index);
9
},
10
archive: function(e) {
11
    var index = parseInt(e.target.parentNode.parentNode.getAttribute("data-index"));
12
    this.model.archive(this.mode !== "archive", index); 
13
},
14
changeStatus: function(e) {
15
    var index = parseInt(e.target.parentNode.parentNode.getAttribute("data-index"));
16
    this.model.changeStatus(e.target.checked, index);       
17
}

Di sini kami menggunakan e.target datang ke handler. Ini menunjuk pada elemen DOM yang memicu peristiwa. Kami mendapatkan indeks ToDo diklik dan memperbarui model dalam koleksi. Dengan keempat fungsi kita selesai kelas kami dan sekarang data ditampilkan ke halaman.

Seperti yang telah disebutkan di atas, kami akan menggunakan pandangan yang sama untuk halaman arsip.

1
list: function(archive) {
2
    var view = ViewsFactory.list();
3
    api
4
    .title(archive ? "Archive:" : "Your ToDos:")
5
    .changeContent(view.$el);
6
    view.setMode(archive ? "archive" : null).render();
7
},
8
archive: function() {
9
    this.list(true);
10
}

Di atas adalah sama rute handler sebagai sebelumnya, tapi kali ini dengan benar sebagai parameter.

Menambahkan & mengedit ToDos

Setelah primer dari tampilan daftar, kita bisa membuat satu lagi yang menunjukkan suatu bentuk untuk menambah dan mengedit tugas. Berikut adalah cara kelas baru ini dibuat:

1
// App.js / views factory

2
form: function() {
3
    if(!this.formView) {
4
        this.formView = new api.views.form({
5
            model: api.todos
6
        }).on("saved", function() {
7
            api.router.navigate("", {trigger: true});
8
        })
9
    }
10
    return this.formView;
11
}

Cukup banyak yang sama. Namun, kali ini kita perlu melakukan sesuatu setelah formulir dikirimkan. Dan itulah maju pengguna ke halaman rumah. Seperti saya katakan, setiap objek yang meluas kelas Backbone.js, adalah sebenarnya peristiwa operator. Ada metode seperti pada dan memicu yang dapat Anda gunakan.

Sebelum kita melanjutkan Lihat kode, mari kita lihat pada HTML template:

1
<script type="text/template" id="tpl-form">
2
    <form>
3
        <textarea><%= title %></textarea>

4
        <button>save</button>

5
    </form>

6
</script>

Kami memiliki sebuah textarea dan tombol. Template mengharapkan parameter judul yang seharusnya menjadi string kosong, jika kita menambahkan tugas baru.

1
// views/form.js

2
app.views.form = Backbone.View.extend({
3
    index: false,
4
    events: {
5
        'click button': 'save'
6
    },
7
    initialize: function() {
8
        this.render();
9
    },
10
    render: function(index) {
11
        var template, html = $("#tpl-form").html();
12
        if(typeof index == 'undefined') {
13
            this.index = false;
14
            template = _.template(html, { title: ""});
15
        } else {
16
            this.index = parseInt(index);
17
            this.todoForEditing = this.model.at(this.index);
18
            template = _.template($("#tpl-form").html(), {
19
                title: this.todoForEditing.get("title")
20
            });
21
        }
22
        this.$el.html(template);
23
        this.$el.find("textarea").focus();
24
        this.delegateEvents();
25
        return this;
26
    },
27
    save: function(e) {
28
        e.preventDefault();
29
        var title = this.$el.find("textarea").val();
30
        if(title == "") {
31
            alert("Empty textarea!"); return;
32
        }
33
        if(this.index !== false) {
34
            this.todoForEditing.set("title", title);
35
        } else {
36
            this.model.add({ title: title });
37
        }   
38
        this.trigger("saved");      
39
    }
40
});

Yang adalah hanya 40 baris kode, tapi itu melakukan pekerjaannya dengan baik. Ada hanya satu peristiwa yang terpasang dan ini adalah mengklik Simpan tombol. Metode render bertindak berbeda tergantung dari parameter berlalu indeks. Sebagai contoh, jika kita mengedit ToDo, kami melewati indeks dan mengambil model yang tepat. Jika tidak, maka bentuk kosong dan tugas baru akan dibuat. Ada beberapa poin yang menarik dalam kode di atas. Pertama, di render kami digunakan .focus() metode untuk membawa fokus ke bentuk sekali pandangan dituliskan. Lagi fungsi delegateEvents yang harus disebut, karena bentuk bisa dilepaskan dan melekat lagi. Simpan metode dimulai dengan e.preventDefault(). Ini menghilangkan perilaku default tombol, yang dalam beberapa kasus dapat menyerahkan formulir. Dan pada akhirnya, setelah semuanya dilakukan kita dipicu acara disimpan memberitahu dunia luar yang ToDo disimpan ke dalam koleksi.

Ada dua metode untuk router yang kita miliki untuk mengisi.

1
// App.js

2
newToDo: function() {
3
    var view = ViewsFactory.form();
4
    api.title("Create new ToDo:").changeContent(view.$el);
5
    view.render()
6
},
7
editToDo: function(index) {
8
    var view = ViewsFactory.form();
9
    api.title("Edit:").changeContent(view.$el);
10
    view.render(index);
11
}

Perbedaan antara keduanya adalah bahwa kita melewati dalam indeks, jika edit /: indeks rute yang cocok. Dan tentu saja judul halaman yang berubah sebagaimana mestinya.

Menghapus catatan dari koleksi

Untuk fitur ini, kita tidak perlu lihat. Seluruh pekerjaan dapat dilakukan langsung di router handler.

1
delteToDo: function(index) {
2
    api.todos.remove(api.todos.at(parseInt(index)));
3
    api.router.navigate("", {trigger: true});
4
}

Kita tahu indeks ToDo yang kami ingin menghapus. Ada metode Hapus di kelas koleksi yang menerima objek model. Pada akhirnya, hanya maju pengguna ke halaman rumah, yang menunjukkan daftar diperbarui.

Kesimpulan

Backbone.js memiliki semua yang Anda butuhkan untuk membangun sebuah halaman yang berfungsi penuh, satu aplikasi. Kita bahkan bisa mengikat sisanya back-end layanan dan kerangka akan menyinkronkan data antara aplikasi Anda dan database. Acara didorong pendekatan mendorong pemrograman modular, bersama dengan arsitektur yang baik. Saya pribadi menggunakan Backbone.js untuk beberapa proyek dan bekerja sangat baik.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.