Home > Article > Web Front-end > Explain the MVC structure design concept of JavaScript's Backbone.js framework_Basic knowledge
What is Backbone.js?
Backbone.js is the first of the top ten JS frameworks. Backbone.js is a heavyweight js MVC application framework and the originator of the js MVC framework. It performs key-value binding and custom event processing through the Models data model, provides a rich set of APIs for enumeration functions through the model collection Collections, handles events through views, and interacts with existing Applications through the JSON interface. .
In short, Backbone is a js library that implements the web front-end MVC pattern
What is MVC?
MVC: The back-end server first obtains the page address through the browser (process 1), parses the URL, gets a URL given to it by the view, then parses it through the controller, and then finds the corresponding data (process 2) After finding the data, return the data Model to the controller (process 3). The controller then processes the data, and finally returns it to the view (process 4), which updates the view. This structure is very clear and easy to implement on the backend
The mechanism of MVC in Backbone
Backbone presents data as models, and you can create models, validate and destroy them, and even save them to the server. When changes in the UI cause model properties to change, the model will trigger the "change" event; all views that display model data will receive notification of this event, and then the views will be re-rendered. You don't need to search the DOM for the element with a specific id to update the HTML manually. — When the model changes, the view changes automatically. ——Baidu Encyclopedia
Pattern: a general approach to problem solving
— Design Patterns: Factory Pattern, Adapter Pattern and Observer Pattern
—Framework patterns: MVC, MVP, MVVM
Controller: Connect the view and model through the controller.
The idea of MVC pattern:
It is to separate the model and the view and connect them through the controller
The server-side MVC pattern is very easy to implement
Model: Model is data. Model is the core of all js applications, including interactive data and a large amount of related logic: conversion, validation, calculated properties and access control. You can extend Backbone.Model
View: The view you can see on the page. Each single data model corresponds to a view View
The web page itself is a large view, which is not easy to separate. Backbone.js is suitable for complex large-scale development and solves these problems for us
backbone module
Backbone has the following modules:
Collector Collection provides unified control over separate data models
Create objects directly
Backbone depends on Underscore.js, and DOM processing depends on Backbone.View and jQuery. Therefore, before introducing Backbone.js, Underscore.js must be introduced before it, and jQuery is best introduced together and finally. 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 is followed by a constructor, and Backbone is used as the namespace of the constructor
Model module
Backbone.Model.extend(properties, [classProperties])
Backbone extends instance methods and static methods through 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>
Static methods actually have one more namespace. The above is to add instance methods and static methods to the constructor
var M = Backbone.Model.extend({})
Use extend to extend the method for the model's constructor. M is the extended constructor
Inherit
<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
集合 Collection
Backbone.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,传入的属性会被自动转换为适合的模型类型。
视图 View
Backbone.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与controller
controller是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的功能。