JavaScript在web應用程式開發前端技術和後端技術的邏輯與運行一塊佔有越來越大的比重.為了協助維護和逐一查看前期邏輯和模組性,MVC模式在近幾年中漸漸普及。其中一種運用廣泛的MVC架構就是Backbone.js。
Backbone中的Models(模型)、Views(視圖)和Controller(控制器)
Backbone.js包含以下幾個主要功能:
- 建立模型(以及模型集合);
- 建立視圖;
- 管理綁定,管理事件兼用不同的模型以及視圖與架構其他部分的聯絡;
- 在模型中使用觀察者模式,一旦模型觸發任何change事件,所有顯示此模型資料的視圖接受到該change事件通知,從而自動進行事件重新渲染;
- 給DOM處理所依賴的jQuery或Zepto提供支援。
第一部分:模型(Models)
建立模型,首先我們建立一個包含資料的Person對象。
- Person = Backbone.Model.extend({
- // Person執行個體的建構函式
- initialize: function() {
- console.log("hello world");
- }
- });
-
- var p = new Person();
很簡單對吧?現在我們為這個Person對象添加一些參數,提供更多的資料,我們添加了姓名和身高屬性。
- var p = new Person({name: "Matt", height:"6\"2""});
-
- console.log(p.get("name"));
如果我們不提供姓名和身高時,這個Person對象的這兩個屬性會為空白,因此,我們現在為Person對象提供預設屬性設定。
- Person = Backbone.Model.extend({
- initialize: function() {
- console.log("hello world");
- },
- defaults: {
- name: "Mark",
- height: "3\""
- }
- });
-
- var p = new Person();
- p.set({name: "Matt", height: "6"2\""});
- console.log(p.get("name"));
Backbone的綁定功能很強大,當Model資料變化的時候,能夠自動的觸發方法,更新視圖View。
- Person = Backbone.Model.extend({
- initialize: function() {
- console.log("hello world");
-
- // 當name屬性改變時,添加一個綁定函數
- this.bind("change:name", function() {
- console.log(this.get("name") + " is now the value for name");
- });
- },
- defaults: {
- name: "Bob Hope",
- height: "unknown"
- }
- });
我們當然希望Backbone模型中的資料是有效,因此我們添加error,validate方法來確保在建立對象前,資料是有效。
- Person = Backbone.Model.extend({
- initialize: function() {
- console.log("hello world");
-
- this.bind("change:name", function() {
- console.log(this.get("name") + " is now the value for name");
- });
-
- // 添加一個和error錯誤綁定的方法,用於處理錯誤資料
- this.bind("error", function( model, error ) {
- console.error(error);
- });
- },
- defaults: {
- name: "Bob Hope",
- height: "unknown"
- },
- validate: function ( attributes ) {
- if( attributes.name == "Joe" ) {
- // 返回出錯資訊
- return "Uh oh, you"re name is Joe!";
- }
- }
- });
-
- var person = new Person();
- person.set({name: "Joe", height:"6 feet"});
-
- console.log(person.toJSON());
第二部分:視圖(Views)
HTML的樣式:
- #container
- button Load
- ul#list
-
- #list-template
- li
- a(href="")
Backbone 調用:
- // 一個簡單的模型
- var Links = Backbone.Model.extend({
- data:[
- { text: "Google", href: "http://google.com" },
- { text: "Facebook", href: "http://facebook.com" },
- { text: "Youtube", href: "http://youtube.com" }
- ]
- });
-
- var View = Backbone.View.extend({
- // 建立建構函式
- initialize: function () {
- console.log("init");
- }
- });
-
- var view = new View();
我們從視圖的選項開始:
- var View = Backbone.View.extend({
- // options --> 提供給建構函式的對象
- initialize: function () {
- console.log(this.options.blankOption);
- }
- });
-
- var view = new View({ blankOption: "empty string" });
- view.blankOption /// 會在console中打出“empty string。
還有一些特殊預設定的options,el參數允許你將該視圖附加到頁面上已存在的元素。
- var View = Backbone.View.extend({
- initialize: function () {
- console.log(this.options.blankOption);
- // this.el -> #在DOM中列出
- }
- });
-
- var view = new View({ el: $("#list") });
你還可以建立一個新的元素:
- var View = Backbone.View.extend({
- initialize: function () {
- console.log(this.options.blankOption);
- // this.tagName --> create a "tagName" item in the DOM
- $("body").append(this.el)
- }
- });
-
- var view = new View({ tagName: "div", className: "class", id: "", attributes: "" }); // --> creates a div tag with class "class"
在這個步驟中,我們要使用一個靜態不變的目標
- var View = Backbone.View.extend({
- initialize: function () {
- console.log(this.el);
- },
- el: "#container"
- });
-
- var view = new View({ model: new Links() }); //from first snippet
然後添加一些事件操作:
- var View = Backbone.View.extend({
- initialize: function () {
- // do nothing
- // render() 會調用兩次render
- },
- el: "#container",
- events: {
- "click button": "render"
- },
- render: function() { // 通常這個方法被Backbone調用
- var data = this.model.get("data");
-
- for (var i=0, l=data.length; i<l; i++){
- var li = this.template
- .clone()
- .find("a")
- .attr("href", data[i].href)
- .text(data[i].text)
- .end();
- this.$el // <-- this.$el 是視圖元素的jQuery對象, this.el 是DOM對象
- .find("ul#list").append(li);
- }
- }
- });
-
- var view = new View({ model: new Links() });
第三部分:路由器(Router)
路由器提供導航和控制,讓我們發出指令到Web應用程式。添加sub-URLs或標籤就能進行導航,還可以通過連結快速定位應用程式準確的特徵。
- var Router = Backbone.Router.extend({
- routes: {
- // 這個會匹配任何url是符合foo/<param>的,並且提供:bar: 作為參數,傳輸到paramtest方法中
- // : 會匹配下一個URI
- // 所以#foo/1 會調用paramtest(1)
- "foo/:bar" : "paramtest",
-
- / * 會匹配全部剩下的URI, 所以 #a/b/c 會調用 func("a/b/c")
- "*action" : "func"
- },
- func: function (action) {
- console.log(action);
- },
- paramtest:function (p) {
- console.log(p);
- }
- });
-
- new Router();
-
- Backbone.history.start();
第四部分:集合(Collections)
集合提供一種機制將多種執行個體模型組合起來,提供強大的功能特性來維護和收集資料到列表中。
- // 這是我們最初的person模型
- var Person = Backbone.Model.extend({
- // initialize在我們建立Person對象時被調用
- initialize: function() {
- console.log("Person is initialized.");
- },
-
- // 預設屬性
- defaults: {
- name: "undefined",
- age: "undefined"
- }
- });
-
- // 建立集合!
- var People = Backbone.Collection.extend({
- // 當集合被建立時調用
- initialize: function() {
- console.log("People Collection is initialized");
- },
-
- // 定義存入集合的資料模型
- model: Person
- });
-
- // 建立一個新的Person對象
- var person = new Person({name:"Joe"});
-
- // 建立一個集合,然後將Person對象加入這個集合中
- var people = new People(person);
- people.add([{name:"Bob"}, {name:"Jim"}]);
-
- // 在控制台中,打出這個資料模型的資料
- console.log(people.toJSON());
於是我們就已經完成了包含了模型和視圖的可用集合。
這是關於Backbone的MVC介紹,在下一篇中,我們會介紹它的具體用法,希望這對大家有所協助。有任何問題,可以留言提問