1. はじめに
最近、私は大規模なオンライン バンキング プロジェクトのフロントエンドの最適化を行っています。これには、シック クライアントの使用が必要です。一般的な考え方は、フロントエンドが Ajax 経由でデータをバックエンドに要求し、それを返すというものです。 Jason 形式で変換し、ページに表示します。このシステムは非常に大規模であるため、シック クライアント ソリューションでは必然的にクライアント側で大量の JS コードを記述する必要があります。どのチームにとっても、大量の非構造化コードを維持するのは非常に不便だと思います。そこでBackBoneが目に留まりました。
これは、JS コードを構造化し、フロントエンド JS コードをオブジェクト指向の方法で編成する方法を提供します。これは、ドメイン駆動設計をフロントエンドに適用するようなもので、非常に大規模なプロジェクトをモジュールに分割できます。 各モジュールは、BackBone の要件に応じて View、Model、Router に分割できます。
バックボーンを介して、データをモデルとして扱うことができ、モデルを介して、データの作成、データ検証の実行、破棄またはサーバーへの保存が可能になります。インターフェイス上の操作によってモデル内の属性が変更されると、モデルは変更イベントをトリガーし、モデルのステータスを表示するために使用されるビューは、モデルによってトリガーされた変更メッセージを受信し、対応する応答を発行して、新しいデータをインターフェースに接続します。完全なバックボーン アプリケーションでは、モデルが変更されたときにビュー自体が更新されるだけなので、特別な ID によって DOM からノードを取得するためのグルー コードを作成したり、HTML ページを手動で更新したりする必要はありません。
2. 特徴
Backbone は、ページ内の大量の JS を構造的に管理し、サーバーやビューとのシームレスな接続を確立し、複雑なアプリケーションを構築するための基本フレームワークを提供するために使用される軽量のフロントエンド フレームワークです。
まず、Backbone の主な機能と特徴を簡単に説明します。
2.1 軽量
Backbone のソースコードはわずか約 1,000 行 (コメントと空白行を削除した後)、ファイル サイズはわずか 16 KB、依存ライブラリ Underscore を含めるとわずか 29 KB です。
Backbone の内部実装を簡単に理解するには、少しの時間を費やすだけで済みます。また、Backbone に基づいて二次開発を行う場合は、少量のコードを作成するだけで済みます。
2.2 構造
Backbone は、ページ内のデータ、ロジック、ビューを簡単に分離し、Backbone に従ってコード構造を整理することができ、プロジェクト内のデータ操作、ビジネス ロジック、ユーザー インターフェイスなどの作業を複数の同僚に割り当てることができます。同時に開発を順序立てて行うことができます。同時に、これは大規模で複雑なプロジェクトのメンテナンスと開発に非常に役立ちます。
2.3 継承メカニズム
Backbone では、アプリケーション内のデータ モデル、コレクション、ビューをオブジェクト指向で整理して、アーキテクチャ全体を明確にすることができ、カスタム メソッドを簡単にオーバーロードしたり拡張したりすることもできます。
2.4 サーバーとのシームレスな接続を確立する
バックボーンにはサーバー データとの一連の相互作用ルールが組み込まれており (REST アーキテクチャを理解していれば簡単に理解できます)、データ同期作業はモデルとフロントエンド開発者で自動的に実行されます。クライアントデータに対して操作を実行すると、Backbone は操作したデータをサーバーに自動的に同期します。
これは非常に興味深いことです。フロントエンド開発者にとってサーバー データ インターフェイスは透過的であり、サーバーとの対話方法について心配する必要がなくなりました。
ただし、サーバーによって提供されるデータ インターフェイスは、Backbone のルールと互換性がある必要もあります。新しいプロジェクトの場合は、この一連のルールを使用してインターフェイスを構築してみることができます。ただし、プロジェクトに安定したインターフェイスのセットがすでにある場合は、インターフェイスの変更のリスクが心配になるかもしれません。
それは問題ではありません。Backbone.sync メソッドをオーバーロードすることで、既存のデータ インターフェイスに適応させることもできます。また、さまざまなクライアント環境に応じてさまざまなデータ インタラクション メソッドを実装することもできます。例えば、ユーザーがPCブラウザ経由でサービスを利用する場合、データはリアルタイムでサーバーに同期され、ユーザーがモバイル端末経由でサービスを利用する場合は、ネットワーク環境の問題を考慮して、まずローカルデータベースにデータを同期することができます。その後、適切なタイミングでサーバーと同期します。これらは、メソッドをオーバーロードするだけで実現できます。
2.5 インターフェースイベント管理
MVC では、インターフェイスのプレゼンテーションとビジネス ロジックを完全に分離したいと考えていますが、ユーザーが生成したインタラクティブ イベント (クリック イベントなど) については、jQuery のバインド メソッドを通じて取得してバインドすることがよくあります。
Backbone のビューは、ユーザー イベントと実行メソッドを順序立てて整理するのに役立ちます。これには、次のような単純な式を宣言するだけで済みます。
events: { // 单击id为”save”的元素时,执行视图的add方法 'click #save': 'add', 'mousedown .button': 'show', 'mouseover .button': 'hide' }
在表达式中,事件名称可以是任意的DOM事件(如click、mouseover、keypress等),元素可以是jQuery支持的任意选择器(如标签选择器、id选择器、class选择器等)。
视图会自动将表达式中的事件绑定到选择器元素,当元素的事件被触发后,视图会自动调用表达式中绑定的方法。
2.6 轻量级模板解析
模板解析是Underscore中提供的一个方法。为什么我要在介绍Backbone特性时引入Underscore中的方法?因为该方法能帮助我们更好地分离视图结构和逻辑,且Underscore是Backbone必须依赖的库。
模板解析方法能允许我们在HTML结构中混合嵌入JS代码,就像在JSP页面中嵌入Java代码一样:
<ul> <% for(var i = 0; i < len; i++) { %> <li><%=data[i].title%></li> <% } %> </li>
通过模板解析,我们不需要在动态生成HTML结构时拼接字符串,更重要的是,我们可以将视图中的HTML结构独立管理(例如:不同的状态可能会显示不同的HTML结构,我们可以定义多个单独的模板文件,按需加载和渲染即可)。
2.7 自定义事件管理
在Backbone中,你可以使用on或off方法绑定和移除自定义事件。在任何地方,你都可以使用trigger方法触发这些绑定的事件,所有绑定过该事件的方法都会被执行,如:
var model = new Backbone.Model(); // 在model对象中向自定义事件custom绑定两个函数 model.on('custom', function(p1, p2) { // todo }); model.on('custom', function(p1, p2) { // todo }); // 触发custom事件,将调用上面绑定的两个函数 model.trigger('custom', 'value1', 'value2'); // 移除custom事件中绑定的所有方法 model.off('custom'); // 触发custom事件,但不会执行任何函数,已经事件中的函数已经在上一步被移除 model.trigger('custom');
如果你熟悉jQuery,你会发现它们与jQuery中的bind、unbind和trigger方法非常类似。
另外,Backbone支持一个特殊事件”all”,当在一个对象中绑定了名为”all”的事件后,该对象在触发任何事件时,都会同时触发”all”事件中绑定的方法。有时这种方法会非常有用,例如我们可以通过”all”事件监听对象状态的变化。
3.路由器
在单页应用中,我们通过JavaScript来控制界面的切换和展现,并通过AJAX从服务器获取数据。
可能产生的问题是,当用户希望返回到上一步操作时,他可能会习惯性地使用浏览器“返回”和“前进”按钮,而结果却是整个页面都被切换了,因为用户并不知道他正处于同一个页面中。
对于这个问题,我们常常通过Hash(锚点)的方式来记录用户的当前位置,并通过onhashchange事件来监听用户的“前进”和“返回”动作,但我们发现一些低版本的浏览器(例如IE6)并不支持onhashchange事件。
Backbone提供了路由控制功能,通过Backbone提供的路由器,我们能通过一个简单的表达式将路由地址和事件函数绑定在一起,例如:
var CustomRouter = Backbone.Router.extend({ routes : { '' : 'index', // 当URL Hash在根目录时执行index方法:url# 'list' : 'getList', // 当URL Hash在list节点时执行getList方法:url#list 'detail/:id' : 'query', // 当URL Hash在detail节点时执行query方法,并将detail后的数据作为参数传递给query方法:url#list/1001 '*error' : 'showError' // 当URL Hash不匹配以上规则时, 执行error方法 }, index : function() { alert('index'); }, getList : function() { alert('getList'); }, query : function(id) { alert('query id: ' + id); }, showError : function(error) { alert('error hash: ' + error); }, }); var custom = new CustomRouter(); Backbone.history.start();
请尝试将这段代码复制到你的页面中,并依次访问以下地址(其中URL表示你的页面地址):
URL URL#list URL#detail/1001 URL#hash1 URL#hash2
Please try again using the browser's "Back" and "Forward" buttons to switch back and forth between the addresses you just entered.
You can see that when the URL Hash changes, the bound method will be executed. When an undefined Hash is encountered, the showError method will be executed and the undefined Hash will be passed to this method.
Backbone will record address changes through Hash by default. For lower version browsers that do not support onhashchange, it will monitor Hash changes through setInterval heartbeat, so you don't have to worry about browser compatibility issues.
For browsers that support the HTML5 pushState feature, Backbone also allows you to create personalized URLs through pushState, but this requires some adaptations on your web server.
3. Applicability of Backbone
Backbone is not as adaptable as jQuery. If you are preparing to build a large or complex single-page web application, then Backbone is perfect.
If you want to apply Backbone to your website page, and the page does not have complex logic and structure, then it will only make your page more cumbersome and difficult to maintain.
If your project is not complex, but you really like a certain feature of it (maybe the data model, view management, or router), then you can extract this part of the source code from Backbone, because in Backbone, each The dependencies between modules are not very strong, and you can easily obtain and use one of the modules.
4. Dependent libraries
You cannot use Backbone independently because its basic functions, DOM operations, and AJAX all rely on third-party libraries.
4.1 Underscore
(required)
Underscore is a basic function library used to improve development efficiency. It encapsulates common operations on collections, arrays, objects, and functions. Just like jQuery encapsulates DOM objects, you can easily access and operate JavaScript internal objects through Underscore.
Underscore also provides some very practical function methods, such as function throttling, template parsing, etc.
Regarding some of the main methods in Underscore, I will introduce it in detail in the next chapter, but before that you must understand: Underscore is a library that Backbone must rely on, because many implementations in Backbone are based on Underscore.
4.2 jQuery and Zepto
(optional)
I believe you are familiar with jQuery. It is a cross-browser DOM and AJAX framework.
For Zepto, you can think of it as the "mobile version of jQuery" because it is smaller, faster, and more suitable for running on the browser of mobile terminal devices. It has the same syntax as jQuery, so you can use it like jQuery.
Zepto currently only supports Webkit-based browsers, so it is compatible with most mobile systems such as iOS, Adnroid, Symbian, Blackberry, and Meego. However, it does not yet support Windows Phone or Firefox OS.
Because jQuery and Zepto have the same syntax, for Backbone, there is no problem whether you use jQuery or Zepto (of course, you can't use both at the same time).
In Backbone, DOM selectors, DOM events and AJAX all use jQuery methods. The reason why they are optional here is that if you are not using the views and AJAX data synchronization functions in Backbone, then you do not need to import them.
If you don't want to use jQuery or Zepto, but use another or custom library, there will be no problem as long as your library implements the same DOM selectors, event management, and AJAX methods as jQuery syntax.
Backbone allows you to dynamically configure the third-party libraries you need to use through the setDomLibrary method. This situation is often used:
Although your custom library contains methods with the same syntax as jQuery, the global variables are not $, and you want to keep the existing naming. At this time you can set it to the object referenced internally by Backbone through the setDomLibrary method.
You want to decide which library is more appropriate to use by examining the user's environment. For example: If the user accesses via a PC browser, jQuery is loaded; if the user accesses via a mobile terminal, Zepto is loaded.