在本教程中,我們將構(gòu)建我們的第一個(gè) Ionic 應(yīng)用程序 一起學(xué)習(xí) Ionic 的 JavaScript 組件的基礎(chǔ)知識(shí)。這些組件使您的應(yīng)用程序可以輕松訪問(wèn)功能,例如導(dǎo)航和導(dǎo)航欄、無(wú)限滾動(dòng)和列表。如果您尚未設(shè)置 Ionic 或需要刷新如何使用 Ionic CLI,可以查看本系列的第一篇教程。
什么是組件?
組件這個(gè)術(shù)語(yǔ)在前端有些被濫用 開(kāi)發(fā),因?yàn)樵S多框架都有自己的概念來(lái)描述 成分。事實(shí)上,Web Components 作為官方 HTML 標(biāo)準(zhǔn) 可能會(huì)使這個(gè)概念進(jìn)一步復(fù)雜化,所以讓我們明確定義什么是組件 在離子中。
一般意義上,組件是一個(gè)實(shí)現(xiàn) 由某種形式的編碼約定封裝的功能集。在 換句話說(shuō),您可以將組件視為隔離特定組件的一種方式 應(yīng)用程序其余部分的功能。你可以想想在 HTML 中如何 是不同類(lèi)型的表單輸入,每一個(gè)都是一種類(lèi)型 具有特定功能的組件。
在 Ionic 中,有兩種類(lèi)型的組件,CSS 和JavaScript。 CSS 組件被實(shí)現(xiàn)為一組 CSS 類(lèi),這些類(lèi) 修改元素以賦予其特定的外觀,例如標(biāo)題欄。
JavaScript 組件在技術(shù)上是作為 Angular 指令實(shí)現(xiàn)的,它們是 用作應(yīng)用程序中的 HTML 元素。他們提供了更豐富的 特征。這通常包括用戶(hù)與其交互的能力或 應(yīng)用程序以其他方式管理組件。例如,標(biāo)簽允許 根據(jù)用戶(hù)選擇選項(xiàng)卡顯示或隱藏的內(nèi)容。
在本教程中 我們將重點(diǎn)關(guān)注一些 JavaScript 組件。在本系列的后面部分,我們將仔細(xì)研究 CSS 組件。
有時(shí),Ionic 將組件同時(shí)實(shí)現(xiàn)為 CSS 和 JavaScript 組件,例如選項(xiàng)卡組件。這意味著您決定使用哪一個(gè)。我通常建議選擇 JavaScript 實(shí)現(xiàn)。在大多數(shù)情況下,使用的開(kāi)銷(xiāo) JavaScript 組件可以忽略不計(jì),我相信它們使您的代碼更容易編寫(xiě) 與合作。
源文件
在本教程中, we are going to create an app from scratch and we will continue enhancing the?app in the rest of this series.?The premise of this 應(yīng)用程序是創(chuàng)建一個(gè)公民信息應(yīng)用程序,為用戶(hù)提供 有關(guān)當(dāng)?shù)卦O(shè)施的信息,例如圖書(shū)館和公園。
在這個(gè) 在教程中,我們首先構(gòu)建一個(gè)顯示公園列表的應(yīng)用程序 在芝加哥,并使用無(wú)限滾動(dòng)來(lái)保持加載結(jié)果,只要它們 可用。我們將在下一個(gè)教程中擴(kuò)展該應(yīng)用的功能集。
我創(chuàng)建了一個(gè) API,可以提供應(yīng)用所需的信息。該 API 基于 在 Google 地圖 API 上。您可以自己運(yùn)行該 API,但需要獲取 來(lái)自 Google 的自定義 API 密鑰和說(shuō)明可以在 API 項(xiàng)目上找到。 如果使用提供的 API 時(shí)出現(xiàn)任何問(wèn)題,例如有人濫用 API 如果超過(guò) API 使用限制,運(yùn)行您自己的版本應(yīng)該會(huì)有所幫助。
您可以在 Heroku 上預(yù)覽正在運(yùn)行的應(yīng)用,并在 GitHub 上查看已完成的項(xiàng)目。 不過(guò),我鼓勵(lì)您跟隨我一起構(gòu)建應(yīng)用程序。
1. 設(shè)置項(xiàng)目
首先,您需要開(kāi)始一個(gè)新項(xiàng)目。我們可以通過(guò)運(yùn)行以下命令來(lái)做到這一點(diǎn):
ionic start civinfo https://github.com/ionic-in-action/starter
這將下載一個(gè)入門(mén)包,其中包含一個(gè)空的 讓我們開(kāi)始使用的 Ionic 模板(專(zhuān)為與我的書(shū)《Ionic in Action》一起使用而構(gòu)建)。進(jìn)入目錄,cd civinfo,運(yùn)行ionic 服務(wù)。
您現(xiàn)在可以預(yù)覽在 http://localhost:8100(或在由 離子)。我建議打開(kāi)瀏覽器的開(kāi)發(fā)者工具以確認(rèn)您看到 空白屏幕。是的,應(yīng)該是白屏。我還建議使用 Chrome 預(yù)覽您的應(yīng)用時(shí)進(jìn)行設(shè)備模擬。
2. 設(shè)置基本導(dǎo)航組件
導(dǎo)航是如此重要,我們應(yīng)該從這里開(kāi)始 設(shè)計(jì)我們的應(yīng)用程序。主要導(dǎo)航組件是 ionNavBar 和 ionNavView。大多數(shù)應(yīng)用程序 有一個(gè)設(shè)計(jì)功能,其中有一個(gè)帶有各種標(biāo)題和操作的導(dǎo)航欄 按鈕,然后其余區(qū)域?qū)iT(mén)用于顯示內(nèi)容 當(dāng)前視圖。
ionNavBar和 ionNavView 組件提供了該功能以及一些內(nèi)置智能來(lái)幫助我們解決問(wèn)題。我們的應(yīng)用程序?qū)⒂袔讞l路線 結(jié)束了,但我們?cè)诒窘坛讨兄粯?gòu)建了一個(gè)。
Ionic 在后臺(tái)使用 UI Router 來(lái)管理導(dǎo)航 和路由。如果你熟悉它,那么你就認(rèn)識(shí)它 在 Ionic 中的實(shí)現(xiàn)。有很多細(xì)微差別,但我們?cè)诒窘坛讨斜3趾?jiǎn)單。 最常見(jiàn)和簡(jiǎn)單的用途是定義您的各個(gè)頁(yè)面中的每一個(gè)。 應(yīng)用程序作為一種狀態(tài),即 Ionic/UI 定義特定視圖的路由器方式。
為了讓我們開(kāi)始,我們首先包括 將兩個(gè)導(dǎo)航組件放入 www/index.html 中,如下所示, 將其放入體內(nèi)。
<ion-nav-bar class="bar-balanced"></ion-nav-bar><ion-nav-view></ion-nav-view>
將代碼添加到 index.html 后,您可以重新加載 應(yīng)用程序,并且應(yīng)該會(huì)看到應(yīng)用程序頂部出現(xiàn)一個(gè)綠色條。
您已定義 ionNavBar 組件,該組件會(huì)自動(dòng)顯示在屏幕頂部。稍后,當(dāng)我們創(chuàng)建個(gè)人時(shí) 視圖,這些視圖將能夠?qū)?biāo)題和附加按鈕傳遞給 展示。它足夠智能,知道不同的導(dǎo)航欄應(yīng)該有多高 設(shè)備。這在不同平臺(tái)上并不一致,所以這非常有幫助。導(dǎo)航欄是 給定一個(gè) bar-balanced 給它一個(gè)綠色。
然后就是ionNavView,也就是 為每個(gè)視圖呈現(xiàn)內(nèi)容的占位符。一旦我們定義了 一個(gè)視圖,它將在此處渲染生成的標(biāo)記并自動(dòng)調(diào)整 占用導(dǎo)航欄定位后剩余的可用空間。
導(dǎo)航組件是 JavaScript 的示例 組件(也稱(chēng)為 Angular 指令)。它們看起來(lái)像自定義 HTML 標(biāo)簽,當(dāng)一起使用時(shí),它們足夠智能,可以使標(biāo)題欄與 當(dāng)前視圖并根據(jù)用戶(hù)的導(dǎo)航呈現(xiàn)正確的內(nèi)容 選擇。不過(guò),為了看到這一點(diǎn),我們需要添加一些狀態(tài)。讓我們 首先創(chuàng)建第一個(gè)顯示公園列表的狀態(tài)。
3. 添加公園列表視圖
該應(yīng)用程序的主要目的是顯示公民列表 相關(guān)資源。最初,這將是一個(gè)公園列表,但我們將對(duì)其進(jìn)行擴(kuò)展,以包括圖書(shū)館等其他類(lèi)型的資源。我們想 在此視圖中包含一些功能:
- 用標(biāo)題更新導(dǎo)航欄
- 從 API 加載公園列表
- 以適合移動(dòng)設(shè)備的方式顯示項(xiàng)目列表 格式
- 如果底部允許加載更多項(xiàng)目 達(dá)到,使用無(wú)限滾動(dòng)
- 顯示每個(gè)項(xiàng)目的圖像
第 1 步:設(shè)置地點(diǎn)狀態(tài)、控制器和模板
現(xiàn)在我們對(duì)此視圖有了一些目標(biāo),讓我們從 添加我們的 JavaScript 文件來(lái)注冊(cè)這個(gè)視圖。在以下位置創(chuàng)建一個(gè)新文件 places.js www/views/places/?并向其中添加以下內(nèi)容:
angular.module('App') .config(function($stateProvider) { $stateProvider.state('places', { url: '/places', controller: 'PlacesController as vm', templateUrl: 'views/places/places.html' }); }) .controller('PlacesController', function() { });
我們使用以下方法為 UI Router 聲明一個(gè)新?tīng)顟B(tài) $stateProvider.state() 方法。這只能在 Angular 的 angular.config() 方法中進(jìn)行配置。當(dāng)你聲明一個(gè)狀態(tài)時(shí),你首先傳遞一個(gè) 用于命名路由的字符串,在本例中為 places。然后你可以傳遞一個(gè)對(duì)象 定義狀態(tài)的各種屬性,例如 URL、控制器和模板。您可以查看 UI Router 文檔以了解所有可能的配置 選項(xiàng)。
我們聲明了一個(gè)新?tīng)顟B(tài),將其命名為 places, 為它分配一個(gè) /places 的 URL,使用 controller as 語(yǔ)法命名為 controller,并且 列出了要加載的 templateUrl 。這是一個(gè)相當(dāng)常見(jiàn)的狀態(tài)定義, 你會(huì)發(fā)現(xiàn)它與其他州的使用方式基本相同。控制器 這里聲明的是空的,但我們很快就會(huì)添加它。
該模板是視圖的重要組成部分,描述了 該視圖的視覺(jué)方面。大多數(shù)視圖邏輯和行為將是 在控制器和模板中管理。我們的狀態(tài)聲明我們要加載 模板的 HTML 文件,但我們還沒(méi)有制作一個(gè)。讓我們通過(guò)以下方式解決這個(gè)問(wèn)題 在 www/views/places/ 處創(chuàng)建一個(gè)新文件 places.html,并添加以下代碼。
<ion-view view-title="Local Parks"><ion-content></ion-content></ion-view>
到目前為止,在此模板中,我們已經(jīng)聲明了 ionView 和 ionContent 組件。 ionView 組件是您放置的包裝器 一個(gè)旨在加載到 ionNavView 組件中的模板 較早宣布。 view-title 屬性還用于傳遞導(dǎo)航欄應(yīng)顯示的標(biāo)題。
ionContent 組件是一個(gè)有用的內(nèi)容包裝器, 這有助于確保內(nèi)容空間的大小適合可用屏幕 空間,幫助管理滾動(dòng),并可以公開(kāi)其他不常用的 行為。加載此視圖后,您將看到導(dǎo)航欄標(biāo)題顯示為“本地公園”。
現(xiàn)在我們需要確保應(yīng)用程序加載要執(zhí)行的腳本 將 places.js 添加到 index.html 中,如下所示。我建議 將其添加到 標(biāo)記之前。
<script src="views/places/places.js"></script>
您可以查看該應(yīng)用,但仍然看不到 視圖出現(xiàn)。要查看該視圖,請(qǐng)導(dǎo)航至 http://localhost:8100/#/places。這 狀態(tài)定義中映射的 URL 可用于導(dǎo)航至路線。然后它應(yīng)該如下圖所示,標(biāo)題設(shè)置為“Local Parks”。
立即學(xué)習(xí)“Java免費(fèi)學(xué)習(xí)筆記(深入)”;
這還不是太令人興奮,但這代表了最 您可能在大多數(shù)情況下都會(huì)設(shè)置的基本視圖。現(xiàn)在讓我們開(kāi)始工作吧 加載數(shù)據(jù)并將其顯示在屏幕上。
第 2 步:加載數(shù)據(jù)
在我們可以做很多其他事情之前,我們需要 加載一些數(shù)據(jù)。為此,我們需要添加一個(gè) Angular 服務(wù) 幫助我們管理地理位置。在以后的教程中,用戶(hù)的位置將 被設(shè)備檢測(cè)到。在那之前,我們將手動(dòng)將其設(shè)置為 芝加哥,我最喜歡的城市之一。
打開(kāi) www/js/app.js 并添加 以下服務(wù)到文件末尾。它應(yīng)該與現(xiàn)有的 來(lái)自 angular.module 的方法。
.factory('Geolocation', function() { return { "formatted_address": "Chicago, IL, USA", "geometry": { "location": { "lat": 41.8781136, "lng": -87.6297982 } }, "place_id": "ChIJ7cv00DwsDogRAMDACa2m4K8" }; })
這是一個(gè)返回對(duì)象的 Angular 服務(wù) 與 Google Maps API 返回的芝加哥結(jié)果相匹配。我們現(xiàn)在有詳細(xì)信息 以便我們可以在那里裝載公園。
接下來(lái),我們將更新控制器以加載列表 來(lái)自 API。為簡(jiǎn)單起見(jiàn),我使用以下方式加載數(shù)據(jù) 控制器中的$http 服務(wù)。最好的做法是將其抽象出來(lái) 變成一個(gè)服務(wù)。再次打開(kāi) www/views/places/places.js 并更新 像這樣的控制器:
.controller('PlacesController', function($http, Geolocation) { var vm = this; var base = 'https://civinfo-apis.herokuapp.com/civic/places?type=park&location=' + Geolocation.geometry.location.lat + ',' + Geolocation.geometry.location.lng; vm.places = []; vm.load = function load() { $http.get(base).then(function handleResponse(response) { vm.places = response.data.results; }); }; vm.load(); });
控制器有一個(gè) vm.load() 方法來(lái)執(zhí)行 HTTP 請(qǐng)求并將結(jié)果存儲(chǔ)在 vm.places 中。保存后,您將在瀏覽器的開(kāi)發(fā)人員工具中看到 HTTP 請(qǐng)求觸發(fā)。即使 如果您熟悉 Angular,您可能不認(rèn)識(shí)在 vm 變量上存儲(chǔ)數(shù)據(jù)的確切方法。如果您需要了解一些情況,我建議您查看 John Papa 的帖子,了解為什么這是推薦的方法。
要顯示數(shù)據(jù),我們還需要更新模板并循環(huán)顯示公園列表。打開(kāi) www/views/places/places.html 并進(jìn)行更新,如下所示。
<ion-view view-title="Local Parks"><ion-content><ion-list><ion-item ng-repeat="place in vm.places" class="item-avatar"> @@##@@ <h2>{{place.name}}</h2> <p>{{place.formatted_address}}</p> </ion-item></ion-list></ion-content></ion-view>
在模板中,我們使用 ionList 和 ionItem 組件。 ionList 組件是最有用的組件之一,因?yàn)榱斜硎且粋€(gè)非常有用的組件。 由于較小的屏幕和典型的使用,移動(dòng)設(shè)備中常見(jiàn)的設(shè)計(jì)選擇 縱向。與使用 ul 和 li 的列表非常相似,ionList 包裝任何 ionItem 元素的數(shù)量。
列表可以采用多種不同的外觀,并且 在這個(gè)例子中,列表項(xiàng)通過(guò)聲明在左側(cè)顯示圖像 item-avatar ionItem 上的類(lèi)。同樣的方法也可以用在消息應(yīng)用程序中,其中您有一個(gè)包含每個(gè)人頭像的聊天列表。
在 ionItem 內(nèi),您顯示名稱(chēng)和地址。默認(rèn)樣式是自動(dòng)截?cái)啵ㄊ褂?CSS)任何溢出的文本以保留項(xiàng)目 高度相同。
我們已加載公園列表并將其顯示為 使用 ionList 和 ionItem 進(jìn)行列表。我們可以更進(jìn)一步并添加 當(dāng)用戶(hù)滾動(dòng)到末尾時(shí)無(wú)限滾動(dòng)以加載附加結(jié)果 列表(如果可用)。
第 3 步:向列表添加無(wú)限滾動(dòng)
使列表自動(dòng)加載附加項(xiàng)目 當(dāng)用戶(hù)滾動(dòng)到底部時(shí),我們可以使用 ionInfiniteScroll 成分。該組件放置在列表的末尾,監(jiān)視何時(shí) 用戶(hù)已經(jīng)滾動(dòng)到最后,然后調(diào)用一個(gè)可以加載附加內(nèi)容的方法 項(xiàng)目。它還具有內(nèi)置的加載旋轉(zhuǎn)器,以指示有更多項(xiàng)目 正在加載。當(dāng)響應(yīng)解析時(shí),微調(diào)器會(huì)隱藏。
我們的 API 還必須支持某種形式的分頁(yè)。 上班。在這種情況下,Google Maps API 提供了一個(gè)必須傳遞的令牌 加載下一組結(jié)果。我們需要更新控制器來(lái)管理 這個(gè)邏輯讓我們從更新 www/views/places/places.js 開(kāi)始,如下所示。
.controller('PlacesController', function($http, $scope, Geolocation) { var vm = this; var base = 'https://civinfo-apis.herokuapp.com/civic/places?type=park&location=' + Geolocation.geometry.location.lat + ',' + Geolocation.geometry.location.lng; var token = ''; vm.canLoad = true; vm.places = []; vm.load = function load() { var url = base; if (token) { url += '&token=' + token; } $http.get(url).then(function handleResponse(response) { vm.places = vm.places.concat(response.data.results); token = response.data.next_page_token; if (!response.data.next_page_token) { vm.canLoad = false; } $scope.$broadcast('scroll.infiniteScrollComplete'); }); }; });
我們添加了一個(gè)新屬性 vm.canLoad,它是一個(gè)布爾值,指示是否有其他項(xiàng)目要加載。這 默認(rèn)為 true 。在請(qǐng)求返回之前,我們不知道是否存在 是否有其他可用項(xiàng)目。
vm.load() 方法已更新以附加令牌,如果 可用的。響應(yīng)處理程序現(xiàn)在將結(jié)果連接到 大批。這意味著第二頁(yè)結(jié)果將添加到第一頁(yè)之后。這 只要有更多結(jié)果,Google Maps API 就會(huì)返回 next_page_token 可以加載的。如果該屬性缺失,我們可以假設(shè)沒(méi)有 要加載更多項(xiàng)目,并且 vm.canLoad 設(shè)置為 false。無(wú)限滾動(dòng)組件使用此值來(lái)確定何時(shí)停止加載更多項(xiàng)目。
最后的更改是添加了 $scope.$broadcast(‘scroll.infiniteScrollComplete’)。 無(wú)限滾動(dòng)組件不知道 HTTP 請(qǐng)求何時(shí)發(fā)生 已完成或恰好在保存時(shí)禁用加載符號(hào)。所以, 該組件監(jiān)聽(tīng)事件以更新自身。在 在這種情況下,scroll.infiniteScrollComplete 事件告訴組件 停止旋轉(zhuǎn)器并繼續(xù)觀察用戶(hù)滾動(dòng)到底部。
最后一步是在模板中啟用此功能。打開(kāi) www/views/places/places.html 并在 ionList 末尾添加一行 和 ionContent 組件。
<ion-infinite-scroll on-infinite="vm.load()" ng-if="vm.canLoad"></ion-infinite-scroll>
無(wú)限滾動(dòng)組件現(xiàn)已在您的 模板。它開(kāi)始監(jiān)視組件何時(shí)可見(jiàn),這也會(huì)在加載時(shí)觸發(fā),因?yàn)槟菚r(shí)沒(méi)有任何地方可見(jiàn),并且 無(wú)限滾動(dòng)組件可見(jiàn)。它調(diào)用聲明的方法 on-infinite 當(dāng)它變得可見(jiàn)時(shí)(這里是 vm.load() )并等待滾動(dòng) 已觸發(fā)完整事件。
ngIf 用于禁用 一旦 API 返回了所有可能的結(jié)果,就會(huì)無(wú)限滾動(dòng)。在這種情況下,滾動(dòng)到 底部不再觸發(fā)更多資源的加載。
使用無(wú)限滾動(dòng)時(shí),使用 ngIf 很重要 禁用它。可以很容易地以這樣的方式實(shí)現(xiàn)該組件: 組件嘗試加載并加載并且永遠(yuǎn)不會(huì)停止。
這樣就完成了地點(diǎn)視圖。回過(guò)頭來(lái)看,還蠻有 模板中 12 行 HTML 和大約 20 行啟用的一些功能 控制器中的 JavaScript 行。
摘要
我們研究了您將在 Ionic 應(yīng)用中經(jīng)常使用的許多組件。
- Ionic JavaScript 組件用作 HTML 元素,并且可以以協(xié)調(diào)的方式工作。
- Ionic 具有 ionNavView 和 ionNavBar 以支持不同視圖的協(xié)調(diào)導(dǎo)航。
- ionList 和 ionItem 組件可以輕松構(gòu)建適合移動(dòng)設(shè)備的列表。
- ionInfiniteScroll 組件會(huì)自動(dòng)觸發(fā)調(diào)用以加載其他項(xiàng)目并將其附加到列表中。
下一個(gè)教程將介紹 Ionic 提供的一些有用的服務(wù),例如加載指示器和彈出窗口。
創(chuàng)建 Ionic 模板并贏得 1000 美元
如果您已經(jīng)熟悉 Ionic 框架,那么您可能需要考慮參加 Envato 的 Ionic 模板最受歡迎競(jìng)賽。如何?創(chuàng)建一個(gè)獨(dú)特的 Ionic 模板并在 2016 年 4 月 27 日之前將其提交到 Envato Market。
五個(gè)最佳模板將獲得 1000 美元。感興趣的?請(qǐng)?jiān)L問(wèn)競(jìng)賽網(wǎng)站,了解有關(guān)競(jìng)賽要求和指南的詳細(xì)信息。