一、前端MVC概要 1.1、庫與框架的區別 框架是一個軟體的半成品,在全局範圍內給了大的約束。庫是工具,在單點上給我們提供功能。框架是依賴庫的。AngularJS是框架而jQuery則是庫。 1.2、AMD與CMD 在傳統的非模塊化JavaScript開發中有許多問題:命名衝突、文件依賴、跨環境共用 ...
一、前端MVC概要
1.1、庫與框架的區別
框架是一個軟體的半成品,在全局範圍內給了大的約束。庫是工具,在單點上給我們提供功能。框架是依賴庫的。AngularJS是框架而jQuery則是庫。
1.2、AMD與CMD
在傳統的非模塊化JavaScript開發中有許多問題:命名衝突、文件依賴、跨環境共用模塊、性能優化、職責單一、模塊的版本管理、jQuery等前端庫層出不窮,前端代碼日益膨脹
AMD規範及其代表:RequireJS
非同步模塊定義(Asynchronous Module Definition),它是依賴前置 (因為依賴必須一開始就寫好)會先儘早地執行(依賴)模塊 , 相當於所有的require都被提前了
CMD規範及其代表:SeaJS
(Common Module Definition)模塊定義規範
一個模塊就是一個文件;它推崇依賴就近想什麼時候require就什麼時候載入,實現了 懶載入, 延遲執行 (as lazy as possible)
1.2、前端MVC概要
MVC的核心理念是:你應該把管理數據的代碼(Model)、業務邏輯的代碼(Controller)、以及向用戶展示數據的代碼(View)清晰的分離開
模型:代表應用當前的狀態
視圖:用於展示數據,用於介面
控制器:用來管理模型和視圖之間的關係
1.3、React
React 起源於 Facebook 的內部項目,因為該公司對市場上所有 JavaScript MVC 框架,都不滿意,就決定自己寫一套,用來架設 Instagram 的網站。做出來以後,發現這套東西很好用,就在2013年5月開源了。由於 React 的設計思想極其獨特,屬於革命性創新,性能出眾,代碼邏輯卻非常簡單。所以,越來越多的人開始關註和使用,認為它可能是將來 Web 開發的主流工具。支持虛擬DOM(Virtual DOM)和組件化的開發。
ReactJS官網地址:http://facebook.github.io/react/
Github地址:https://github.com/facebook/react
1.4、Vue.js
Vue.js是一個輕巧、高性能、可組件化的MVVM庫,同時擁有非常容易上手的API,作者是尤雨溪是中國人。
易用
已經會了HTML,CSS,JavaScript?即刻閱讀指南開始構建應用!
靈活
簡單小巧的核心,漸進式技術棧,足以應付任何規模的應用。
性能
17kb min+gzip 運行大小
超快虛擬 DOM
最省心的優化
1.5、AngularJS簡介
AngularJS是一個前端MVVM框架。
angular的英文字面意思是:有角的; 用角測量的
AngularJS是協助搭建單頁面工程(SPA)的開源前端框架。它通過MVC模式使得開發與測試變得更容易。
AngularJS試圖成為WEB應用中的一種端對端的解決方案。它將指導開發整個應用。
AngularJS於2009年發佈第一個版本,由Google進行維護,壓縮版94k。
1.3版後不再支持IE8
1.3版後不支持全局控制器
2.0版 alpha
git倉庫:https://github.com/angular/
http://www.angularjs.cn/中文社區
http://www.apjs.net/ 中文網
a web framework for modern web apps
1.5.1、AngularJS特點
1、功能強大,完善的前端MVVM框架,包含模板,數據雙向綁定,路由,模塊化,服務,過濾器,依賴註入等所有功能;
2、聲明式風格、直觀、易於操作、訪問和實現
3、支持單元測試、本身基於TDD完成
4、致力於減輕開發人員在開發AJAX應用過程中的痛苦
5、angular 是最適合CRUD的SPA 單頁面的應用程式
不適合SEO、交互頻繁的,如游戲之類交互體驗網站
AngularJS的核心組件:
1.6、第一個AngularJS程式
如果要開發基於angularJS的項目,則先要添加對angularJS的引用,有如下幾個方法:
1)、去angular官網或git下載,地址:https://github.com/angular/
2)、使用cdn
3)、安裝node.js,使用npm獲取
示例代碼:
<!DOCTYPE html> <!--指定angular托管的範圍--> <html ng-app="app01"> <head> <meta charset="UTF-8"> <title>angular01</title> </head> <body> <!--指定控制器的作用範圍--> <div ng-controller="HelloController"> name:<input type="text" ng-model="message"/> <p> {{"Hello "+message}} </p> </div> <!--引入angularjs框架--> <script src="js/angular146/angular.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //定義模塊,指定依賴項為空 var app01 = angular.module("app01", []); //定義控制器,指定控制器的名稱,$scope是全局對象 app01.controller("HelloController", function($scope) { //在全局作用域對象上添加屬性message,並指定值 $scope.message = "Angular!"; }); </script> </body> </html>
運行結果:
第一個AngularJS程式要註意的地方:
1、HTML裡面沒有Class或者ID來標記在哪裡添加事件監聽器
2、當HelloController把message設置成Hello World時,我們沒有必要註冊任何事件監聽或者編寫任何回調函數。
3、HelloController只是一個普通的JavaScript類,不需要繼承Angular所提供的任何東西。
4、HelloController可以獲取它所需要的$scope對象,則沒有必要去創建它,依賴註入
5、當文本框中的值發生變化時$scope對象中的值立即變化,模型與視圖雙向綁定
6、沒有必要自己調用HelloController的構造方法,或者指定何時去調用
1.7、定義AngularJS模塊
AngularJS模塊是一種容器、它把代碼隔離並組織成簡單、整潔、可復用的塊。
angular.module(name,[requires],[configFn]);
name:模塊名稱,必須指定
requires:依賴項,要被添加到註入器服務提供這個模塊使用的模塊名的數組,如果需要另一個模塊的功能,你需要將它添加在列表中,所有依賴的實在數組中指定依賴的模塊。
configFn:模塊配置階段調用的另一個函數。
//1、定義模塊,指定模塊名稱,依賴對象,配置函數 angular.module("mocule1",['$window','$http'],function(){ //服務提供者 $provider.value("PI","3.14"); }); //2、定義模塊,簡化,無依賴,無配置函數 var module2=angular.module("module2",[]); //3、獲得指定模塊 var module3=angular.module("module3"); //4、同時同義模塊與控制器 angular.module("module4",[]).controller("controller4",function(){ });
二、模板與數據綁定
2.1、顯示普通文本
angular中,把HTML文件被稱為模板
顯示文本
方法一:
<span>{{item.title}}</span>
方法二:
<span ng-bind="item.title"></span>
示例:
<!DOCTYPE html> <!--指定angular托管的範圍--> <html ng-app="app01"> <head> <meta charset="UTF-8"> <title>模板與數據綁定</title> </head> <body> <!--指定控制器的作用範圍--> <div ng-controller="HelloController"> <p> name:{{user.name}} </p> <p> hobby:<span ng-bind="user.hobby"></span> </p> <p> info:{{user.info}} </p> </div> <!--引入angularjs框架--> <script src="js/angular146/angular.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //定義模塊,指定依賴項為空 var app01 = angular.module("app01", []); //定義控制器,指定控制器的名稱,$scope是全局對象 app01.controller("HelloController", function($scope) { //在全局作用域對象上添加對象,並指定值 $scope.user = { "name": "zhangguo", "hobby": "coding", "info": "<hr/>detail" }; }); </script> </body> </html>
結果:
當載入慢時的效果:
方法二與方法一的區別:
使用模塊標簽{{ }}載入慢或渲染慢時用戶將看到標簽,而ng-bind不會,但是使用模塊要方便。
2.2、顯示HTML
為了安全預設的HTML都將被轉義。$sce 是 angularJS 自帶的安全處理模塊,$sce.trustAsHtml(str) 方法便是將數據內容以 html 的形式進行解析並返回。將此過濾器添加到 ng-bind-html 、data-ng-bind-html? 所綁定的數據中,便實現了在數據載入時對於 html 標簽的自動轉義。
示例代碼:
<!DOCTYPE html> <!--指定angular托管的範圍--> <html ng-app="app01"> <head> <meta charset="UTF-8"> <title>模板與數據綁定</title> </head> <body> <!--指定控制器的作用範圍--> <div ng-controller="HelloController"> <p> {{info}} </p> <p> ng-bind:<span ng-bind="info"></span> </p> <p> ng-bind-html:<span ng-bind-html="info"></span> </p> </div> <!--引入angularjs框架--> <script src="js/angular146/angular.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //定義模塊,指定依賴項為空 var app01 = angular.module("app01", []); //定義控制器,指定控制器的名稱,$scope是全局對象 app01.controller("HelloController", function($scope,$sce) { $scope.info=$sce.trustAsHtml("<h2>html info</h2>"); }); </script> </body> </html>
運行結果:
2.3、ng-model
使用ng-model屬性把元素綁定到模型屬性上,如果$scope上不存在,則立即創建,如果存在則綁定,允許同時綁定到多個HTML元素上。
<input type="checkbox" ng-model="isChecked"/>
$scope中有isChecked與沒有isChecked的區別
ngModel 會嘗試使用表達式的計算結果來綁定到當前域上的屬性。如果屬性在當前域上不存在,它會立即創建並添加到當前域
示例:
<!DOCTYPE html> <!--指定angular托管的範圍--> <html ng-app="app01"> <head> <meta charset="UTF-8"> <title>模板與數據綁定</title> </head> <body> <!--指定控制器的作用範圍--> <div ng-controller="HelloController"> <p> 同意: <input type="checkbox" ng-model="isChecked"/> </p> 允許:<input type="text" ng-model="isChecked"/> <p> {{isChecked}} </p> </div> <!--引入angularjs框架--> <script src="js/angular146/angular.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //定義模塊,指定依賴項為空 var app01 = angular.module("app01", []); //定義控制器,指定控制器的名稱,$scope是全局對象 app01.controller("HelloController", function($scope) { $scope.isChecked=true; }); </script> </body> </html>
結果:
要註意$scope中是否存在該模型,如果有則會初始化數據。
2.4、ng-change
ng-change屬性來指定一個控制器方法,變化時觸發
當用戶改變輸入時計算給出的表達式。表達式會被立即計算,不像 JavaScript的onchange事件只會在最後一次改變時觸發(通常,當用戶離開表單元素或按回車鍵時)。當值的變化來自於模型時,不會對錶達式進行計算。
這個指令需要同時給出 ngModel
示例:
<!DOCTYPE html> <!--指定angular托管的範圍--> <html ng-app="app01"> <head> <meta charset="UTF-8"> <title>模板與數據綁定</title> </head> <body> <!--指定控制器的作用範圍--> <div ng-controller="HelloController"> <p> 本金: <input type="text" ng-model="money" ng-change="getInterest()"/> </p> <p> 利息:{{interest}} </p> <p> 總收益:{{interest*1+money*1}} </p> </div> <!--引入angularjs框架--> <script src="js/angular146/angular.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //定義模塊,指定依賴項為空 var app01 = angular.module("app01", []); //定義控制器,指定控制器的名稱,$scope是全局對象 app01.controller("HelloController", function($scope) { $scope.getInterest=function(){ $scope.interest=$scope.money*Math.random(); } }); </script> </body> </html>
結果:
2.5、$watch
用於監視對象的變化,可以獲得變化前的值與變化後的值。
上面的做法有一個潛在的問題,只有當用戶在文檔框中輸入值的時候我們才會去計算,如還有更多的輸入框,每一個輸入框都要綁定。
$scope.$watch(‘fund.interest’,callback);
示例代碼:
<!DOCTYPE html> <!--指定angular托管的範圍--> <html ng-app="app01"> <head> <meta charset="UTF-8"> <title>模板與數據綁定</title> </head> <body> <!--指定控制器的作用範圍--> <div ng-controller="HelloController"> <p> 本金: <input type="text" ng-model="money"/> </p> </div> <!--引入angularjs框架--> <script src="js/angular146/angular.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //定義模塊,指定依賴項為空 var app01 = angular.module("app01", []); //定義控制器,指定控制器的名稱,$scope是全局對象 app01.controller("HelloController", function($scope) { $scope.$watch("money",function(newVal,old){ console.log("舊值:"+old+" 新值:"+newVal); }); }); </script> </body> </html>
運行結果:
2.6、事件
angularjs的內置指令中有許多封裝好的事件指令,如下所示:
示例:
<!DOCTYPE html> <!--指定angular托管的範圍--> <html ng-app="submitExample"> <head> <meta charset="UTF-8"> <title>模板與數據綁定</title> </head> <body> <!--指定控制器的作用範圍--> <form ng-submit="submit()" ng-controller="ExampleController"> Enter text and hit enter: <input Type="text" ng-model="text" name="text" ng-copy="copy()" /> <input Type="submit" id="submit" value="Submit" /> <pre>list={{list}}</pre> <p> <input ng-copy="copied=true" ng-init="copied=false; value='copy me'" ng-model="value"> <br/> 是否複製: {{copied}} <br/><br/> <input ng-paste="paste=true" ng-init="paste=false" placeholder='paste here'> <br/> 是否粘貼: {{paste}} </p> </form> <!--引入angularjs框架--> <script src="js/angular146/angular.min.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> angular.module('submitExample', []) .controller('ExampleController', ['$scope', function($scope) { $scope.list = []; $scope.text = 'hello'; $scope.submit = function() { if($scope.text) { $scope.list.push(this.text); $scope.text = ''; } }; }]); </script> </body> </html>
結果:
ng-submit它可以防止預設動作(這對錶單意味著向伺服器發送請求和重新載入當前頁),但只在表單沒包含action, data-action或x-action屬性時。
2.7、ng-repeat迭代
ngRepeat指令為集合中的每項實例化一個模板。每個模板的實例擁有自己的域,使用迴圈變數指向當前集合項上,$index指向當前項的索引或鍵值。
特殊屬性應用於每個模板實例的本地域上,包括:
對象集合的修改將會自動更新視圖
為瞭解決重覆元素序列只有一個父元素的情況,ngRepeat (不同於其它ng指令)支持擴展重覆範圍,通過使用ng-repeat-start 和 ng-repeat-end分別定義明確的開始和結束點。ng-repeat-start 指令工作方法類似ng-repeat,但是會重覆從標簽定義本身位置開始到ng-repeat-end定義位置之間的所有HTML代碼。
<header ng-repeat-start="item in items"> Header {{ item }} </header> <div class="body"> Body {{ item }} </div> <footer ng-repeat-end> Footer {{ item }} </footer>
如果上面例子中的items變數的值為['A','B'],則輸出結果為:
<header> Header A </header> <div class="body"> Body A </div> <footer> Foote