Backbone.js란 무엇인가요?
Backbone.js는 상위 10개 JS 프레임워크 중 첫 번째입니다. Backbone.js는 중량급 js MVC 애플리케이션 프레임워크이자 js MVC 프레임워크의 창시자입니다. 모델 데이터 모델을 통해 키-값 바인딩 및 사용자 정의 이벤트 처리를 수행하고, 모델 컬렉션 컬렉션을 통해 열거 기능을 위한 풍부한 API 세트를 제공하고, 보기를 통해 이벤트를 처리하고, JSON 인터페이스를 통해 기존 애플리케이션과 상호 작용합니다.
간단히 말하면 Backbone은 웹 프론트엔드 MVC 패턴을 구현한 js 라이브러리입니다
MVC란 무엇인가요?
MVC: 백엔드 서버는 먼저 브라우저(프로세스 1)를 통해 페이지 주소를 획득하고, URL을 구문 분석하고, 뷰에서 제공된 URL을 얻은 다음 컨트롤러를 통해 이를 구문 분석한 후 해당 데이터를 찾습니다. (프로세스 2) 데이터를 찾은 후 데이터 모델을 컨트롤러에 반환합니다(프로세스 3). 컨트롤러는 데이터를 처리한 후 마지막으로 뷰에 반환하고(프로세스 4) 뷰를 업데이트합니다. 이 구조는 매우 명확하고 백엔드에서 구현하기 쉽습니다
Backbone의 MVC 메커니즘
Backbone은 데이터를 모델로 제공하므로 모델을 생성하고 검증 및 삭제할 수 있으며 서버에 저장할 수도 있습니다. UI 변경으로 인해 모델 속성이 변경되면 모델은 "변경" 이벤트를 트리거합니다. 모델 데이터를 표시하는 모든 보기는 이 이벤트에 대한 알림을 받은 다음 보기가 다시 렌더링됩니다. HTML을 수동으로 업데이트하기 위해 특정 ID를 가진 요소에 대해 DOM을 검색할 필요가 없습니다. — 모델이 변경되면 뷰가 자동으로 변경됩니다. ——바이두백과사전
패턴: 문제 해결을 위한 일반적인 접근 방식
— 디자인 패턴: 팩토리 패턴, 어댑터 패턴, 관찰자 패턴
—프레임워크 패턴: MVC, MVP, MVVM
컨트롤러: 컨트롤러를 통해 뷰와 모델을 연결합니다.
MVC 패턴의 아이디어:
모델과 뷰를 분리하고 컨트롤러를 통해 연결하는 것입니다
서버측 MVC 패턴은 구현하기가 매우 쉽습니다
모델: 모델은 데이터입니다. 모델은 대화형 데이터와 많은 양의 관련 논리(변환, 유효성 검사, 계산된 속성 및 액세스 제어)를 포함하는 모든 js 애플리케이션의 핵심입니다. 특정 메소드를 사용하여 Backbone.Model
보기: 페이지에서 볼 수 있는 보기입니다. 각 단일 데이터 모델은 뷰에 해당합니다. 뷰
웹페이지 자체가 큰 뷰이기 때문에 분리가 쉽지 않습니다. Backbone.js는 복잡한 대규모 개발에 적합하며 이러한 문제를 해결해 줍니다
백본 모듈
백본에는 다음과 같은 모듈이 있습니다:
Collector 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은 생성자의 네임스페이스로 사용됩니다
모델 모듈
Backbone.Model.extend(properties, [classProperties])
백본은 확장을 통해 인스턴스 메서드와 정적 메서드를 확장합니다.
<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({})
모델 생성자의 메서드를 확장하려면 확장을 사용하세요. 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
集合 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的功能。