AngularJS簡介:AngularJS 是一個為動態(tài)WEB應用設計的結(jié)構(gòu)框架,提供給大家一種新的開發(fā)應用方式,這種方式可以讓你擴展HTML的語法,以彌補在構(gòu)建動態(tài)WEB應用時靜態(tài)文本的不足,從而在web應用程序中使用HTML聲明動態(tài)內(nèi)容。
AngularJS有五個主要核心特性,如下介紹:
雙向數(shù)據(jù)綁定—— 實現(xiàn)了把model與view完全綁定在一起,model變化,view也變化,反之亦然。
模板—— 在AngularJS中,模板相當于HTML文件被瀏覽器解析到DOM中,AngularJS遍歷這些DOM,也就是說AuguarJS把模板當做DOM來操作,去生成一些指令來完成對view的數(shù)據(jù)綁定。
MVVM—— 吸收了傳統(tǒng)的MVC設計模式針但又并不執(zhí)行傳統(tǒng)意義上的MVC,更接近于MVVM(Moodel-View-ViewModel)。
依賴注入—— AngularJS擁有內(nèi)建的依賴注入子系統(tǒng),可以幫助開發(fā)人員更容易的開發(fā),理解和測試應用。
指令—— 可以用來創(chuàng)建自定義的標簽,也可以用來裝飾元素或者操作DOM屬性
ionic簡介: ionic是一個強大的_混合式/hybrid_HTML5移動開發(fā)框架,特點是使用標準的HTML、 CSS和JavaScript,開發(fā)跨平臺(目前支持:Android、iOS,計劃支持:Windows Phone、Firefox OS) 的原生App應用。

ionic主要包括三個部分:
CSS框架- 提供原生_App質(zhì)感的CSS樣式模擬_。ionic這部分的實現(xiàn)使用了ionicons圖標樣式庫。
JavaScript框架- ionic基于AngularJS基礎框架開發(fā),遵循AngularJS的框架約束;主要提供了適應移動端UI的 AngularJS的擴展,主要包括指令和服務。此外,ionic使用AngularUI Router來實現(xiàn)前端路由。
命令行/CLI- 命令行工具集用來簡化應用的開發(fā)、構(gòu)造和仿真運行。ionic命令行工具使用了 Cordova,依賴于平臺SDK(Android & iOS)實現(xiàn)將移動web項目打包成原生app。
由于ionic使用了HTML5和CSS3的一些新規(guī)范,所以要求iOS7+/Android4.1+。 在低于這些版本的手機上使用ionic開發(fā)的應用,有時會發(fā)生莫名其妙的問題。
安裝ionic/Install Ionic
首先您需要安裝Node.js. 其次, 安裝最新版本的cordova 和 ioniccommand-line tools. 通過參考Android和iOS官方文檔來安裝.
npm install -g cordova ionic
通過Ionic創(chuàng)建一個項目
使用Ionic官方提供的現(xiàn)成的應用程序模板,或一個空白的項目創(chuàng)建一個Ionic應用。
ionic start myApp blank ?創(chuàng)建一個空白的app項目 (下圖1)
ionic start myApp tabs 創(chuàng)建一個帶有tabs項目(下圖2)
ionic start myApp sidemenu 創(chuàng)建一個帶有滑動的項目(下圖3)

我現(xiàn)在創(chuàng)建一個空白的項目 ionic start myApp blank

然后我們看到有myApp項目生成。如下目錄

然后我們用瀏覽器打開index就可以看的如下圖的東西了。

接著下一步,我們用編輯器打開index.html。觀察里面所引入的文件,我的習慣把跟項目無關(guān)的文件刪除了。你可以不刪除,我也改動了部分文件的位置,之所以叫你觀察里面引入的文件,就是怕你刪錯了,項目啟動不了。改動完結(jié)構(gòu)如下:

其中配置文件,controller,driectives,filter,services,文件都是我新建的。
下面先從app.js說起

這個myApp需要在根節(jié)點啟動。一個項目建議一個這樣的模塊。

上述路由config配置是基于ui-router,因為在index.html已經(jīng)引入了ionic.bundle.min.js文件,這個文件把angular.js和ui-router及ionic所需的組件都幫我們打包好了,所以引用很方便。
打開這個ionic.bundle.min.js看一下就知道合成了什么東西了,如圖:

把6個文件包合成一個了,你可以分別百度看看各是什么包,留給你們思考。
$stateProvider.state(name, {
? ? url: '',
? ?templateUrl:'', // 這個是模板位置
? ?controller: '' // 這個是對應模板的controller名稱!記住是名稱不是位置
});
上述是ui-router的基本用法,詳情用法可以去查看官方文檔。
app.js配置完,下面就配置controller
剛才我們配置完了app.js,我們要新建一個名字叫homeCtrl的controller。命名我建議XXXCtrl或者XXXController,當然以你們項目為標準。

采用閉包的模式創(chuàng)建controller,為了保險防止不必要變量污染的錯誤。其中
angular.module('myApp') 就是載入剛才創(chuàng)建的模塊,然后設置一個叫做homeCtrl的controller,
格式一般都是angular.module('myApp').controller(name, [params, function(params) {}])。
創(chuàng)建完成homeCtrl之后呢,在index.html中引用,如下圖:

好了,我們根據(jù)剛才配置的路由創(chuàng)建完了controller,現(xiàn)在就差模板了。
創(chuàng)建home模板
在剛才創(chuàng)建文檔template文件夾當中,新建一個home.html。也就是剛才配置app.js中的路由中寫的路徑和名字,忘記的回頭看看app.js是怎樣寫的。在剛才創(chuàng)建的home.html,寫上以上內(nèi)容
如下圖:

在項目中我們這樣寫著,凡是帶有<ion-xxx></ion-xxx>都是ionic框架自帶的。這是一個指令,如果你還不明白指令什么意思,沒關(guān)系。你就當做一個帶有某些功能的自定義標簽。
創(chuàng)建home.html模板和homeCtrl.js之后。我們試著啟動,在瀏覽器中打開index.html這個文件,這個文件作為一個項目的入口。ion-view就是這個頁面的頂層,所有內(nèi)容都在這個view中,ion-header就是那個頭部,ion-content就是內(nèi)容。這些都不是必須的,但是我建議這樣寫,因為ionic有些組件是需要在這些標簽里面才能起作用的。然后看到如下圖:

當看到頁面和控制臺都出現(xiàn)“hello world”文字,證明我們成功了,項目啟動成功。
創(chuàng)建app.js和html模板及homeCtrl模板總結(jié)
其實我們寫項目的思路:舉剛才那個例子
1、創(chuàng)建一個app.js,首先能啟動項目,然后配置路由。其中路由需要模板和controller那么問題來了,接著看2、3、步。
2、然后創(chuàng)建模板,XXX.html模板。
3、最后創(chuàng)建XXXCtrl.js的controller。
編寫控制器與模板
下面來點有意思的吧,先來個輪播圖。那就用ionic框架自帶的吧,具體查文檔即可,如下圖:

刷新瀏覽器如下圖:

好了,這證明我們成功了,可以滑動,可以自帶切換。其實還有很多功能,可以查閱文檔嘗試。一般由于手機網(wǎng)站banner都是從后臺讀取數(shù)據(jù)的,那么我們來改寫。在controller獲取數(shù)據(jù),然后賦值給$scope變量,由于頁面和對應controller的$scope有關(guān)聯(lián),所以對應頁面上的屬性也會變好,是不是還是不太明白,那么來看代碼吧。homeCtrl如下:


我們把代碼改成
1、ng-repeat="item in views.slideData track by $index",意思就是從$scope.views.slideData數(shù)組遍歷,item是數(shù)組里面的某一項,track by $index其實是性能優(yōu)化,后續(xù)會講,你也可以不寫直接ng-repeat="item in views.slideData"
2、之前由<img src="路徑"> 這種變成 ?<img ng-src="{{item}}",其中ng-src是一個angular自帶的指令,item是數(shù)組遍歷出來的路徑
從服務器獲取數(shù)據(jù)
啰嗦的話不說了,直接上案例。如圖:

既然要數(shù)據(jù),那么先建一個服務,使用 angular.module 的 factory API創(chuàng)建服務,是最常見也是最靈活的方式。其實還有幾種
factory()
service()
constant()
value()
provider()
,具體詳情查文檔,不過多數(shù)項目用這種(factory)創(chuàng)建方法就滿足需求了。舉個簡單例子
factory() 方法是創(chuàng)建和配置服務的最快捷方式。 factory() 函數(shù)可以接受兩個參數(shù)。
name (字符串)
需要注冊的服務名。
getFn (函數(shù))
這個函數(shù)會在AngularJS創(chuàng)建服務實例時被調(diào)用。
angular.module('myApp')
? ?.factory('myService', function() {
? ? ? ?return {
? ? ? ? ? ?'username': 'auser'
? ? ? ?};
? ?});
要上我們真實的示例代碼了哦,如下圖:

有同學覺得奇怪了,怎么會是app.factory呢?其實app就是angular.module('myApp',[]),我在app.js文件里面把angular.module('myApp',[])賦值給全局變量app了。見下圖:

我們建好了servers。在index.html里面引入哦:

好!創(chuàng)建好servers.js,還有在index中引入。那么怎么在controller中調(diào)用呢?那我們來看看改寫后的controller,如圖:


我們創(chuàng)建services到調(diào)用services里面的ajax請求都成功了,如何在homeCtrl中獲取數(shù)據(jù)呢?
那就先從services改寫開始,如下圖:

homeCtrl怎么獲取數(shù)據(jù)?看下圖:

調(diào)用myFactory.getList()方法為什么后面還跟著一個then的。其實我們使用內(nèi)置的 $http 服務直接同外部進行通信。 $http 服務只是簡單的封裝了瀏覽器原生的 XMLHttpRequest 對象。$http 服務是只能接受一個參數(shù)的函數(shù),這個參數(shù)是一個對象,包含了用來生成HTTP請求的配置內(nèi)容。這個函數(shù)返回一個promise對象, 由于 $http 方法返回一個promise對象,我們可以在響應返回時用 then 方法來處理回調(diào)。如果使用 then 方法,會得到一個特殊的參數(shù),它代表了相應對象的成功或失敗信息,還可以接受兩個可選的函數(shù)作為參數(shù)?;蛘呖梢允褂?success 和 error 回調(diào)代替,至于promise對象是什么,這里就不一一敘述了,寫起來篇幅比較大,還是留給你們查文檔吧。
promise.then(function(resp){
// resp是一個響應對象
}, function(resp) {
// 帶有錯誤信息的resp
});
// 或者使用success/error方法
promise.success(function(data, status, headers, config){
// 處理成功的響應
});
// 錯誤處理
promise.error(function(data, status, headers, config){
// 處理非成功的響應
});
然后看看控制臺輸出什么,還是看圖:

OK!大功告成,我們可以把這些數(shù)據(jù)綁定在$scope上,然后渲染到頁面。還是看圖:



總結(jié):
1、創(chuàng)建services并寫好里面的服務,然后在index.html引入services。
2、homeCtrl中注入依賴services里面的factory服務,調(diào)用里面的方法。
3、在homeCtrl調(diào)用factory服務方法,然后獲取數(shù)據(jù)。再把數(shù)據(jù)賦值給$scope。所以模板也能獲取$scope里面的數(shù)據(jù),那么頁面數(shù)據(jù)就更新了。
編寫過濾器
上面已經(jīng)教會大家如何建立一個services服務獲取數(shù)據(jù),但是有時候我們獲取數(shù)據(jù)回來的數(shù)據(jù)做進一步修改顯示在頁面,下面假如我們有一個需求,我想把姓名全部變成大寫。
1、首先創(chuàng)建一個filter。
2、在index.html引入filter。(這個不說了,請看上面services怎么引入的)

在home.html頁面中,姓名這樣寫。
姓名:{{item.Name | toUpperCaseText}}

那么我現(xiàn)在想把城市變成小寫,怎么弄?留給你們一個作業(yè)吧。
正如前面所見,創(chuàng)建自定義過濾器非常容易。創(chuàng)建自定義過濾器需要將它放到自己的模塊中。過濾器本質(zhì)上是一個會把我們輸入的內(nèi)容當作參數(shù)傳入進去的函數(shù)。上面只是一個簡單的例子,其實就是把數(shù)據(jù)獲取進來,數(shù)據(jù)進來了,你想怎樣處理數(shù)據(jù)就怎樣處理。相當于你小時候,你騙你爸爸媽媽零用錢的時候,錢到你口袋了,至于錢怎么用了,那是你自己的事。當你爸爸媽媽問你拿去干什么的時候,你告訴他了,那就相當于把數(shù)據(jù)處理完渲染在頁面了。過濾器其實內(nèi)置有很多很好用的,需要的時候時不時的查看文檔就行了。用法就是這么簡單。
過濾器總結(jié)
1、分析需求怎樣的數(shù)據(jù)在頁面,查閱內(nèi)置過濾器是否滿足需求。
2、假如需求內(nèi)置過濾器不能滿足,創(chuàng)建filter.js,編寫處理數(shù)據(jù)邏輯。
3、在index.html引入過濾器。在需要用過濾器的加上“|”,例如:{{item.Name | toUpperCaseText}}
頁面之間傳遞數(shù)據(jù)
當我們寫完home.html頁面并且完成了homeCtrl,及通過services獲取后臺服務器的數(shù)據(jù),展示到頁面,證明我們成功了一個小項目的大部分。你可以想象,一個項目都是獲取數(shù)據(jù),展示數(shù)據(jù)(至于怎樣展示,點擊展示還是默認展示,這是交互性的東西),或者提交數(shù)據(jù),提交數(shù)據(jù)本文并沒有說,但是我們已經(jīng)知道怎樣獲取了,提交還困難么。都是差不多的原理。自己翻閱文檔看看$http的方法就可以解決了。我們下面繼續(xù)實現(xiàn)一個需求,點擊剛才的某一項列表,跳到詳情頁。
新建一個詳情頁detail.html,新建一個detailCtrl的控制器,并且配置詳情頁路由。忘記了的可以看看前面新建home的步驟。(記得在index.html引入detailCtrl哦,否則會報下面的錯,看圖)

下面展示路由配置及detail.html頁面和detailCtrl.js



我們配置完路由和新建detail的頁面及controller。我們實現(xiàn)點擊列表跳轉(zhuǎn)到detail頁面,并帶上數(shù)據(jù)。我再啰嗦一次,本文帶有<ion-xxx>都是ionic框架自帶的,ion-view就是這個頁面的頂層,所有內(nèi)容都在這個view中,ion-header就是那個頭部,ion-content就是內(nèi)容。這些都不是必須的,但是我建議這樣寫,因為ionic有些組件是需要在這些標簽里面才能起作用的。
那我們點擊列表
思路就是ng-click="views.goDetail(item)"; views.goDetail就是跳轉(zhuǎn)到detail頁面,跳轉(zhuǎn)路由使用$state.go("XXX");XXX代表路由的名稱,item就是你點擊某一項的數(shù)據(jù),看圖:


我們點擊列表的時候既可以,可以看到console把item的內(nèi)容打印出來。

現(xiàn)在需求要實現(xiàn)下面的詳情圖。

如何實現(xiàn)從A頁面==》B頁面,并且把A頁面的數(shù)據(jù)帶到B頁面。下面來探討angular頁面之間的傳遞數(shù)據(jù)方式。下面講5種方法,可能有更多,但是我選常用的講。
1、可以用$rootScope頂級作用域,從A頁面賦值給$rootScope的某個屬性,然后B頁面獲取數(shù)據(jù)賦值到頁面。



結(jié)果,如大家所愿詳情頁能實現(xiàn)剛才的效果了。
2、在A頁面用$state.go("xxx", {obj});配置路由參數(shù),然后在B頁面用$stateParams對象獲取url的參數(shù)。




使用這個方法從home頁面?zhèn)鬟f過來的url
3、在services里面建立一個服務,在A頁面把數(shù)據(jù)傳遞給這個服務,然后在B頁面獲取這個服務的值。為什么可以這樣做?因為services服務里面的方法是共享的,當項目初始化的時候services已經(jīng)實例化了一次(服務是一個單例對象,在每個應用中只會被實例化一次(被 $injector 實例化),并且是延遲加載的(需要時才會被創(chuàng)建)),所以不存在跳轉(zhuǎn)頁面就數(shù)據(jù)沒了。(這個是最佳實踐哦,不過也要看業(yè)務場景。這個是我最常用的)。





頁面之間的傳遞數(shù)據(jù),以上是常用的3種。下面介紹沒那么常用的:
利用localStorage、sessionStorage、cookie在A頁面中存值,然后在B頁面中獲取值,這3個都是可以存儲數(shù)據(jù)。他們之間的區(qū)別你們查文檔吧,哈哈哈~~~~ 留給你們思考。
數(shù)據(jù)綁定
數(shù)據(jù)綁定,從剛一開始從服務獲取數(shù)據(jù),然后把數(shù)據(jù)綁定到$scope上,然后在頁面輸入{{}}花括號輸出,這種就是數(shù)據(jù)綁定了。那我們來個假設,現(xiàn)在有個輸入框,輸入框是多少,列表中的那個人的年齡是多少。
由于這個需求,就是雙向數(shù)據(jù)綁定,可以ng-model用綁定一個變量,這個變量賦值給年齡,那么年齡也跟著變了??聪聢D:



好啦好啦,初始化做完了。下面呢,我們在input輸入框值,改變一下input框里面的值,看看有什么變化。
改變了
輸入框里面的值改變了,上面的年齡值也改變了。證明$scope.views.age的值改變了,這些就是數(shù)據(jù)綁定了。
數(shù)據(jù)綁定總結(jié)
當AngularJS認為某個值可能發(fā)生變化時,它會運行自己的事件循環(huán)來檢查這個值是否變“臟”。如果該值從上次事件循環(huán)運行之后發(fā)生了變化,則該值被認為是“臟”值。這也是Angular可以跟蹤和響應應用變化的方式。這個事件循環(huán)會調(diào)用$digest()循環(huán)(這個你們查查文檔就能知道了)。這個過程被稱作臟檢查(dirty checking)。臟檢查是檢查數(shù)據(jù)模型變化的有效手段。當有潛在的變化存在時,AngularJS會在事件循環(huán)時執(zhí)行臟檢查(查閱文檔)來保證數(shù)據(jù)的一致性。
源碼:百度網(wǎng)盤 http://pan.baidu.com/s/1i59P1cD
假如你打開了源碼。我寫得比較丑別笑話我,里面或許有一些錯誤,望指正,假如我有空可以交流一下。
假如你看到源碼會報這些錯,第一個錯是因為我并沒有引入cordova進去,第2/3/4報錯是因為css源碼的字體丟失了。(問題在home頁的輪播的小圈圈,其實你可以寫樣式把它干掉,問題即可解決)
