Skip to content

四火的唠叨

一个纯正程序员的啰嗦

Menu
  • 所有文章
  • About Me
  • 关于四火
  • 旅行映像
  • 独立游戏
  • 资源链接
Menu

Backbone.js

Posted on 05/08/201210/08/2024 by 四火

backbone

注:教程请参见这里(本文有很多内容都是从这里翻译的),官方网站在这里;综合例子参见这里。

Backbone.js 是一个前端 MVC 框架,model 能够绑定键值对和自定义事件,集合具备可枚举方法的富 API,视图具备事件处理能力,并且可以通过 RESTful 的 JSON 接口和你已有的 API 通信。

backbone2

View

Backbone 里的视图就是用来反映数据模型的,可以监听事件并响应,通过利用 Underscore.js(这个真是一个牛逼哄哄的东西,自己看),还支持了 JavaScript 模板技术,把数据和模板分离开。

“el” 属性就是浏览器创建的一个 DOM 对象的引用,是供 backbone 渲染的画布,每一个 view 都会有这样一个属性,如果不存在,backbone 就会自己定义一个空的 div 来作为 el,现在把”el” 属性定义到 div#search_container,看:

<div id="search_container"></div>

<script type="text/javascript">
    SearchView = Backbone.View.extend({  
        initialize: function(){  
            this.render();  
        },  
        render: function(){  
            //Pass variables in using Underscore.js Template  
            var variables = { search_label: "My Search" };  
            // Compile the template using underscore  
            var template = _.template( $("#search_template").html(), variables );  
            // Load the compiled HTML into the Backbone "el"  
            this.el.html( template );  
        },  
        events: {  
            "click input[type=button]": "doSearch"    
        },  
        doSearch: function( event ){  
            // Button clicked, you can access the element that was clicked with event.currentTarget  
            alert( "Search for " + $("#search_input").val() );  
        }  
    });  

    var search_view = new SearchView({ el: $("#search_container") });  
</script>

<script type="text/template" id="search_template">
    <!-- Access template variables with <%= %> -->
    <label><%= search_label %></label>
    <input type="text" id="search_input" />
    <input type="button" id="search_button" value="Search" />
</script>

上面的代码说明一下:

  • render 方法就是渲染页面的方法;
  • View 层的事件绑定也支持了:
    “click input[type=button]”: “doSearch”;
  • 对于模板的使用,先定义这个模板:
    <script type=”text/template” id=”search_template”>……</script>
    然后模板+数据来生成结果:
    var template = _.template( $(“#search_template”).html(), variables );
    然后再把结果渲染到画布上:
    this.el.html( template );

Model

Model 是 JavaScript 应用的核心,在这里它包括了包含大量逻辑的数据交互、转换、校验,属性的计算和访问控制:

Person = Backbone.Model.extend({  
        defaults: {  
            name: 'Fetus',  
            age: 0,  
            children: []  
        },  
        initialize: function(){  
            alert("Welcome to this world");  
        },  
        adopt: function( newChildsName ){  
            var children_array = this.get("children");  
            children_array.push( newChildsName );  
            this.set({ children: children_array });  
        }  
    });  

var person = new Person({ name: "Thomas", age: 67, children: ['Ryan']});  
    person.adopt('John Resig');  
var children = person.get("children"); // ['Ryan', 'John Resig']

简单说明一下:

  • default 是用来定义 Model 的属性的默认取值的;
  • 设值(setter)可以这样写:
    set({ children: children_array });
  • 而取值(getter)则这样写:
    person.get(“children”)。

再来看看事件绑定的写法(看下面的 bind 方法的调用)和属性校验的写法(validate 方法):

Person = Backbone.Model.extend({  
// If you return a string from the validate function,
// Backbone will throw an error
    validate: function( attributes ){  
        if( attributes.age < 0 && attributes.name != "Dr Manhatten" ){  
            return "You can't be negative years old";  
        }  
    },  
    initialize: function(){  
        alert("Welcome to this world");  
        this.bind("error", function(model, error){  
            // We have received an error, log it, alert it or forget it :)
            alert( error );  
        });  
    }  
});  

Router

Router 以前是被 backbone 称为 Controller 的,它使用 URL 的 hash 来做地址映射。主要的写法有 “*” 和 “:” 两种:

var AppRouter = Backbone.Router.extend({  
    routes: {  
        "/posts/:id/:action": "getPost",  
        "*actions": "defaultRoute" // Backbone will try match the route above first
    },  
    getPost: function( id, action ) {  
        // Note the variable in the route definition being passed in here
        alert( "Get post number " + id );     
    },  
    defaultRoute: function( actions ){  
        alert( actions );   
    }  
});  
// Instantiate the router
var app_router = new AppRouter;  
// Start Backbone history a neccesary step for bookmarkable URL's
Backbone.history.start(); 

稍微说明一下:

  • 如果 URL 为 http://example.com/#/posts/121/delete 的话,那么:
    “/posts/:id/:action” 匹配上了,那么 id=”121″,action=”delete” 这样的参数传到 getPost 方法里;
    如果没匹配上,”121/delete” 将作为参数传到 defaultRoute 方法里。
  • 在创建好所有的 router 之后,一定要调用一下 Backbone.history.start() 方法来 route 你的 URL。

Collection

Collection 其实就是一组 Model 的有序集合。

var Song = Backbone.Model.extend({  
    defaults: {  
        name: "Not specified",  
        artist: "Not specified"
    },  
    initialize: function(){  
        console.log("Music is the answer");  
    }  
});  

var Album = Backbone.Collection.extend({  
    model: Song  
});  

var song1 = new Song({ name: "How Bizarre", artist: "OMC" });  
var song2 = new Song({ name: "Sexual Healing", artist: "Marvin Gaye" });  
var song3 = new Song({ name: "Talk It Over In Bed", artist: "OMC" });  

var myAlbum = new Album([ song1, song2, song3]);  
console.log( myAlbum.models ); // [song1, song2, song3]

说明一下:

  • 对象集合怎么放进去(比如数组形式),它就怎么管理:
    var myAlbum = new Album([ song1, song2, song3]);

文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》

×Scan to share with WeChat

你可能也喜欢看:

  1. 前端解耦的一个最简单示例
  2. A page widgetization practice
  3. Function Invocation Patterns
  4. 从 JavaScript 的单线程执行说起
  5. JavaScript 重构攻略

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

订阅·联系

四火,啰嗦的程序员一枚,现居西雅图

Amazon Google Groovy Hadoop Haskell Java JavaScript LeetCode Oracle Spark 互联网 亚马逊 前端 华为 历史 同步 团队 图解笔记 基础设施 工作 工作流 工具 工程师 应用系统 异步 微博 思考 技术 数据库 曼联 测试 生活 眼界 程序员 管理 系统设计 缓存 编程范型 美股 英语 西雅图 设计 问题 面向对象 面试

分类

  • Algorithm and Data Structure (30)
  • Concurrency and Asynchronization (6)
  • System Architecture and Design (43)
  • Distributed System (18)
  • Tools Frameworks and Libs (13)
  • Storage and Data Access (8)
  • Front-end Development (33)
  • Programming Languages and Paradigms (55)
  • Testing and Quality Assurance (4)
  • Network and Communication (6)
  • Authentication and Authorization (6)
  • Automation and Operation Excellence (13)
  • Machine Learning and Artificial Intelligence (6)
  • Product Design (7)
  • Hiring and Interviews (14)
  • Project and Team Management (14)
  • Engineering Culture (17)
  • Critical Thinking (25)
  • Career Growth (57)
  • Life Experience and Thoughts (45)

推荐文章

  • 聊一聊分布式系统中的时间
  • 谈谈分布式锁
  • 常见分布式系统设计图解(汇总)
  • 系统设计中的快速估算技巧
  • 从链表存在环的问题说起
  • 技术面试中,什么样的问题才是好问题?
  • 从物理时钟到逻辑时钟
  • 近期面试观摩的一些思考
  • RSA 背后的算法
  • 谈谈 Ops(汇总 + 最终篇):工具和实践
  • 不要让业务牵着鼻子走
  • 倔强的程序员
  • 谈谈微信的信息流
  • 评审的艺术——谈谈现实中的代码评审
  • Blog 安全问题小记
  • 求第 K 个数的问题
  • 一些前端框架的比较(下)——Ember.js 和 React
  • 一些前端框架的比较(上)——GWT、AngularJS 和 Backbone.js
  • 工作流系统的设计
  • Spark 的性能调优
  • “残酷” 的事实
  • 七年工作,几个故事
  • 从 Java 和 JavaScript 来学习 Haskell 和 Groovy(汇总)
  • 一道随机数题目的求解
  • 层次
  • Dynamo 的实现技术和去中心化
  • 也谈谈全栈工程师
  • 多重继承的演变
  • 编程范型:工具的选择
  • GWT 初体验
  • java.util.concurrent 并发包诸类概览
  • 从 DCL 的对象安全发布谈起
  • 不同团队的困惑
  • 不适合 Hadoop 解决的问题
  • 留心那些潜在的系统设计问题
  • 再谈大楼扔鸡蛋的问题
  • 几种华丽无比的开发方式
  • 我眼中的工程师文化
  • 观点的碰撞
  • 谈谈盗版软件问题
  • 对几个软件开发传统观点的质疑和反驳
  • MVC 框架的映射和解耦
  • 编程的未来
  • DAO 的演进
  • 致那些自嘲码农的苦逼程序员
  • Java 多线程发展简史
  • 珍爱生命,远离微博
  • 网站性能优化的三重境界
  • OSCache 框架源码解析
  • “ 你不适合做程序员”
  • 画圆画方的故事

近期评论

  • panshenlian.com on 初涉 ML Workflow 系统:Kubeflow Pipelines、Flyte 和 Metaflow
  • panzhixiang on 关于近期求职的近况和思考
  • Anonymous on 闲聊投资:亲自体验和护城河
  • 四火 on 关于近期求职的近况和思考
  • YC on 关于近期求职的近况和思考
  • mafulong on 常见分布式基础设施系统设计图解(四):分布式工作流系统
  • 四火 on 常见分布式基础设施系统设计图解(八):分布式键值存储系统
  • Anonymous on 我裸辞了
  • https://umlcn.com on 资源链接
  • Anonymous on 我裸辞了
© 2025 四火的唠叨 | Powered by Minimalist Blog WordPress Theme