这里有新鲜出炉的 Javascript 教程,程序狗速度看过来!
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
这篇文章主要介绍了 JavaScript 的 Backbone.js 框架的 MVC 结构设计理念, 相比较于 Angular.js, 同样为 MVC 结构的 Backbone 则显得轻巧许多, 需要的朋友可以参考下
什么是 Backbone.js?Backbone.js 是十大 JS 框架之首,Backbone.js 是一个重量级 js MVC 应用框架,也是 js MVC 框架的鼻祖。它通过 Models 数据模型进行键值绑定及 custom 事件处理,通过模型集合器 Collections 提供一套丰富的 API 用于枚举功能,通过视图 Views 来进行事件处理及与现有的 Application 通过 JSON 接口进行交互。
简而言之,Backbone 是实现了 web 前端 MVC 模式的 js 库
什么是 MVC?MVC:后端服务器首先(过程 1)通过浏览器获取页面地址,对网址进行解析,得到视图 View 给它的一个网址,然后通过控制器 controller 进行解析,然后去找对应的数据(过程 2),找到数据后,再将数据 Model 返回给控制器(过程 3),控制器 controller 再对数据进行加工,最后返回给视图(过程 4),即更新视图 View。这种结构在后端是非常清晰且易实现的
Backbone 中 MVC 的机制 Backbone 将数据呈现为模型, 你可以创建模型、对模型进行验证和销毁,甚至将它保存到服务器。 当 UI 的变化引起模型属性改变时,模型会触发 "change" 事件; 所有显示模型数据的视图会接收到该事件的通知,继而视图重新渲染。 你无需查找 DOM 来搜索指定 id 的元素去手动更新 html。 — 当模型改变了,视图便会自动变化。———百度百科
模式:一种解决问题的通用方法
—设计模式:工厂模式、适配器模式和观察者模式 —框架模式:MVC、MVP、MVVM 控制器:通过控制器来连接视图与模型。
MVC 模式的思想:
就是把模型与视图分离,通过控制器来连接他们 服务器端 MVC 模式非常容易实现 Model:模型即数据,模型 是所有 js 应用程序的核心,包括交互数据及相关的大量逻辑: 转换、验证、计算属性和访问控制。你可以用特定的方法扩展 Backbone.Model
View:即你在页面上所能看到的视图。每一个单一的数据模型对应一个视图 View
web 页面本身就是一个很大的 view,不太容易做到分离操作,backbone.js 适合复杂的大型开发,并为我们解决了这些难题
backbone 的模块 backbone 有如下几个模块:
集合器 Collection 是对单独的数据模型进行统一控制
直接创建对象 Backbone 依赖于 Underscore.js, DOM 处理依赖于 Backbone.View 和 jQuery ,因此,在引入 Backbone.js 之前,Underscore.js 必须在它之前引入,而 jQuery 也最好一并引入,最后再引入 Backbone.js
- <head lang="en">
- <meta charset="UTF-8">
- <title>
- </title>
- <script src="jquery-2.0.3.min.js">
- </script>
- <script src="underscore-min.js">
- </script>
- <script src="backbone.js">
- </script>
- </head>
- <body>
- var model = new Backbone.Model(); var col = new Backbone.Collection();
- var view = new Backbone.View();
- </body>
new 后面是一个构造函数,而 Backbone 是作为构造函数的命名空间来使用的
Model 模块
- Backbone.Model.extend(properties, [classProperties])
Backbone 通过 extend 来扩展实例方法和静态方法:
- <script type="text/javascript">
- //extend接收的第一个参数是json格式的字符串,用来扩展实例方法
- //第二个参数也是json格式的字符串,用来扩展静态方法
- var M = Backbone.Model.extend({
- abc: function() { //实例方法
- alert("hello backbone");
- }
- },
- {
- def: function() { //静态方法
- alert("hi");
- }
- });
- var model = new M;
- model.abc(); //实例方法要用实例对象来访问
- M.def(); //静态方法直接挂载到了构造函数上,可以通过构造函数来直接访问
- </script>
静态方法其实就是多了一个命名空间。以上是给构造函数添加实例方法和静态方法
- var M = Backbone.Model.extend({})
通过 extend 来为模型的构造函数扩展方法,M 就是扩展之后的构造函数
继承
- <script type="text/javascript">
- //继承
- var Mod = backbone.Model.extend({
- abc : function(){
- alert(123);
- }
- });
- var ChildMod = Mod.extend();
- var model = new ChildMod;
- model.abc();//子类继承了父类的方法
- </script>
Backbone 源码结构
1: (function() {
2: Backbone.Events // 自定义事件
3: Backbone.Model // 模型构造函数和原型扩展
4: Backbone.Collection // 集合构造函数和原型扩展
5: Backbone.Router // 路由配置器构造函数和原型扩展
6: Backbone.History // 路由器构造函数和原型扩展
7: Backbone.View // 视图构造函数和原型扩展
8: Backbone.sync // 异步请求工具方法
9: var extend = function (protoProps, classProps) {...} // 自扩展函数
10: Backbone.Model.extend = Backbone.Collection.extend = Backbone.Router.extend = Backbone.View.extend = extend; // 自扩展方法
11: }).call(this); JS MVC 职责划分 M 模型
业务模型:业务逻辑、流程、状态、规则 (核心)数据模型:业务数据、数据校验、增删改查(AJAX) V 视图
(核心)视图:定义、管理、配置 模板:定义、配置、管理 组件:定义、配置、管理 (核心)用户事件配置、管理 用户输入校验、配置、管理 C 控制器 / 分发器
(核心)事件分发、模型分发、视图分发 不做数据处理、业务处理,即业务无关 扩展:权限控制、异常处理等 C 是 JSMVC 框架的核心,实现集中式配置和管理,可以有多个控制器 工具库
主要是异步请求、DOM 操作,可以依赖于 jQuery 等
Model 指的是一条一条的数据,而集合 Collection 指的是对 Model 中的多条数据进行管理。
模型 Model 我们用 Backbone.Model 表示应用中所有数据,models 中的数据可以创建、校验、销毁和保存到服务端。
对象赋值的方法 1、直接定义,设置默认值
- Trigkit = Backbone.Model.extend({
- initialize : function () {
- alert('hi!');
- },
- defaults:{
- age : '22',
- profession : 'coder'
- }
- });
- var coder = new Trigkit;
- alert(coder.get('age'));//22
2、 赋值时定义
- <script type="text/javascript">
- Trigkit = Backbone.Model.extend({
- initialize: function() {
- alert('hi!');
- }
- });
- var t = new Trigkit;
- t.set({
- name: 'huang',
- age: '10'
- });
- alert(t.get('name'));
- </script>
对象中的方法
- <script type="text/javascript" src="Underscore.js">
- </script>
- <script type="text/javascript" src="backbone-1.1.2.js">
- </script>
- <script type="text/javascript">
- var Trigkit4 = Backbone.Model.extend({
- initialize: function() {
- alert("hello world!");
- },
- defaults: {
- name: 'zhangsan',
- age: 21
- },
- aboutMe: function() {
- return '我叫' + this.get('name') + ',今年' + this.get('age') + '岁';
- }
- });
- var t = new Trigkit4;
- alert(t.aboutMe());
- </script>
当模型实例化时,他的 initialize 方法可以接受任意实例参数,其工作原理是 backbone 模型本身就是构造函数,所以可以使用 new 生成实例:
- var User = Backbone.Model.extend({
- initialize: function(name) {
- this.set({
- name: name
- });
- }
- });
- var user = new User('trigkit4');
- alert(user.get('name'), 'trigkit4'); //trigkit4
看下 backbone 的源码:
- var Model = Backbone.Model = function(attributes, options) {
- var attrs = attributes || {};
- options || (options = {});
- this.cid = _.uniqueId('c');
- this.attributes = {};
- if (options.collection) this.collection = options.collection;
- if (options.parse) attrs = this.parse(attrs, options) || {};
- attrs = _.defaults({},
- attrs, _.result(this, 'defaults'));
- this.set(attrs, options);
- this.changed = {};
- this.initialize.apply(this, arguments);
- };
- initialize: function() {},
- //initialize是默认的空函数
Model 的事件绑定 为了能及时更新 view,我们需要通过事件绑定机制来处理和响应用户事件:
- <script type="text/javascript">
- var Task = Backbone.Model.extend({
- initialize: function() {
- this.on("change:name",
- function(model) {
- alert("my name is : " + model.get("name"));
- });
- }
- });
- var task = new Task({
- name: "oldname",
- state: "working"
- });
- task.set({
- name: "trigkit"
- });
- // object.on(event, callback, [context])
- </script>
- </head>
关于事件绑定,有 on,off,trigger,once,listenTo,stopListening,listenToOnce 等方法,具体参照:http://documentcloud.github.io/backbone/#Events
集合 CollectionBackbone.Collection 就是一个 Model 对象的有序集合。因为 Model 是一条数据记录,也就是说,Collection 相当于是一个数据集。具有增加元素,删除元素,获取长度,排序,比较等一系列工具方法,说白了就是一个保存 models 的集合类。
- <script type="text/javascript">
- var Book = Backbone.Model.extend({
- defaults: {
- title: 'default'
- },
- initialize: function() {
- alert('hello backbone!'); //弹出3次
- }
- });
- BookShelf = Backbone.Collection.extend({
- model: Book
- });
- var book1 = new Book({
- title: 'book1'
- });
- var book2 = new Book({
- title: 'book2'
- });
- var book3 = new Book({
- title: 'book3'
- });
- //var bookShelf = new BookShelf([book1, book2, book3]); //注意这里面是数组,或者使用add
- var bookShelf = new BookShelf;
- bookShelf.add(book1);
- bookShelf.add(book2);
- bookShelf.add(book3);
- bookShelf.remove(book3);
- //基于underscore这个js库,还可以使用each的方法获取collection中的数据
- bookShelf.each(function(book) {
- alert(book.get('title'));
- });
- </script>
collection.model 覆盖此属性来指定集合中包含的模型类。可以传入原始属性对象(和数组)来 add, create, 和 reset,传入的属性会被自动转换为适合的模型类型。
视图 ViewBackbone.View 中可以绑定 dom 元素和客户端事件。页面中的 html 就是通过 views 的 render 方法渲染出来的,当新建一个 view 的时候通过要传进一个 model 作为数据
view.$el: 一个视图元素的缓存 jQuery 对象。 一个简单的引用,而不是重新包装的 DOM 元素。 一个简单的 View:
- <head>
- <meta charset="UTF-8">
- <title>
- Document
- </title>
- <script type="text/javascript" src="jquery-1.9.1.min.js">
- </script>
- <script type="text/javascript" src="Underscore.js">
- </script>
- <script type="text/javascript" src="backbone-1.1.2.js">
- </script>
- <script type="text/javascript">
- var TestView = Backbone.View.extend({ //创建一个view,其实就是一个HTML的DOM节点
- initialize: function() {
- this.render();
- },
- render: function() { // 渲染方法
- this.$el.html('Hello World'); //this.el就是HTML节点,通过jQuery的html方法填充内容
- return this;
- }
- });
- $(function() {
- var test = new TestView({
- el: $('#body')
- }); // 以目标节点为el参数,创建一个view的实例,render函数将会被自动调用并将渲染结果填充到el中
- //test.render(); // 如果没在 initialize 里调用 render 的话,就需要在这里调用一次
- });
- </script>
- </head>
- <body>
- <div id="body">
- </div>
- </body>
elview.el 所有的视图都拥有一个 DOM 元素(el 属性),即使该元素仍未插入页面中去。 视图可以在任何时候渲染,然后一次性插入 DOM 中去,这样能尽量减少 reflows 和 repaints 从而获得高性能的 UI 渲染。 this.el 可以从视图的 tagName, className, id 和 attributes 创建,如果都未指定,el 会是一个空 div。 -- 官网
扩展方法 extend 模型、集合、视图、路由器都有一个 extend 方法,用于扩展原型属性和静态属性,创建自定义的模型、集合、视图、路由器类。
- Backbone.Model.extend
- Backbone.Model.extend(properties, [classProperties])
要创建自己的 Model 类,你可以扩展 Backbone.Model 并提供实例 properties(属性) , 以及可选的可以直接注册到构造函数的 classProperties(类属性)。
- Backbone.View.extend
- Backbone.View.extend(properties, [classProperties])
开始创建自定义的视图类。 通常我们需要重载 render 函数,声明 events, 以及通过 tagName, className, 或 id 为视图指定根元素。 Backbone.View 通过绑定视图的 render 函数到模型的 "change" 事件 — 模型数据会即时的显示在 UI 中。
- Backbone.Collection.extend
- Backbone.Collection.extend(properties, [classProperties])
通过扩展 Backbone.Collection 创建一个 Collection 类。实例属性参数 properties 以及 类属性参数 classProperties 会被直接注册到集合的构造函数。
- Backbone.Router.extend
- Backbone.Router.extend(properties, [classProperties])
开始创建一个自定义的路由类。当匹配了 URL 片段便执行定义的动作,并可以通过 routes 定义路由动作键值对。
Router 与 controllercontroller 是 Backbone 0.5 以前的叫法,现在改名叫 Router 了。
Backbone.Router 为客户端路由提供了许多方法,并能连接到指定的动作(actions)和事件(events)。 页面加载期间,当应用已经创建了所有的路由,需要调用 Backbone.history.start()
查看下面示例:
- <script type="text/javascript">
- var AppRouter = Backbone.Router.extend({
- routes: {
- "index" : "index",
- "task/:id": "task",
- "*acts": "tasklist"
- },
- index: function() {
- alert("index");
- },
- tasklist: function(action) {
- alert(action);
- },
- task: function(id) {
- alert(id);
- }
- });
- var app = new AppRouter;
- Backbone.history.start();
- </script>
在浏览器里打开页面后,在 url 的 html 后面依次加上:
- #/index
- #/task/1
- #/test/xxxx
将分别弹出出:index, 1, test/xxxx
这就是 Router 的功能。
来源: http://www.phperz.com/article/17/0406/267167.html