使用ionic+angular+phonegap开发APP入门

有时候朋友问我是做什么的?我说以前是用PHP后台,最近是用H5写前台APP(俗称的Hybrid App);
在公司做了几个H5的项目之后,有时候也想抽空研究下H5写一些APP;总觉得写APP的开发更加有底气。尽管我偶尔有空也会研究下android,swift(Objective-C实在是难懂,没兴趣深入研究),也希望H5能开发一些不错的APP;
国内有包括APPCan等公司慢慢在发力,是很不错的趋势;由于mac上面无法使用APPCAN,所以我就没继续研究了,就看国外是怎么的一个过程;偶尔的机会发现了有人用ionic+angularjs+phonegap,很不错的尝试;于是我也想摸索下;

结论:使用上述的方法开发app,是可行的,至少我再android+IOS上面打包是成功了,体验还可以,开发比较方便,基于一些现成的组件;能在1~2天开发一个简单的demo;效率比较高,不过你需要对angularjs有一定的熟悉和了解;H5也一样;所以我也是慢慢学习慢慢研究;

入门必须:
(1) 看一遍ionic的文档,http://ionicframework.com/
Ionic 是一个用HTML,CSS 跟JS 开发的一个用于移动设备的web app 开发框架,采用 Sass与AngularJS 开发。

(2) 看一遍phonegap的文档;目前phonegap又取名为cordova;有些常用的命令总结如下:

项目例子:http://my.oschina.net/nosand/blog/294011
ionic:
Create hybrid mobile apps with the web technologies you love.
Free and open source,Ionic offers a library of mobile-optimized HTML,
CSS and JS components,gestures,and tools for building highly interactive apps.
Built with Sass and optimized for AngularJS.

Qunee有一个上海地铁图的例子,有客户希望转成mobile app,考察过android的webview,以及PhoneGap等多种Hybrid App方案后,最后选择使用ionic,准确的说是ionic + PhoneGap + Qunee ionic是一种基于HTML5创建Hybrid应用的前端框架,借助phoneGap + angularJS实现一套跨平台,轻量的移动UI方案,本文将介绍借助ionic实现移动版Qunee上海地图的示例
背景知识

安装ionic所需软件环境 – java,android sdk等

ionic实际上是集大成者,借助了多种技术,自身是一套UI框架,结合PhoneGap实现跨平台移动APP,需要先安装好依赖的程序,比如nodejs,java,ADT,ant,xcode等,并设置好java_home,添加android sdk tool到环境变量

mac os x下安装ant

brew update
brew install ant
#mac osx 下,打开.bash_profile文件
cd~
open.bash_profile
#设置相关的Path,mac os x下增加类似下面的内容
exportJAVA_HOME=/usr/libexec/java_home-v1.8

# android
export PATH=${PATH}:/Users/macbook/WorkSpace/android-sdk-macosx/platform-tools:/Users/macbook/WorkSpace/android-sdk-macosx/tools

安装ionic和cordova

需要首先安装好nodejs,然后通过npm来安装

npm install -g cordova ionic
更多请参考官方文档+google http://ionicframework.com/getting-started/
创建ionic项目q-metro

使用下面的命令创建一个新的项目
ionic start q-metro
初始目录结构如下

<!DOCTYPE html> <html> <head> <Meta charset="utf-8"> name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no,width=device-width"<title></title> <link href="http://www.webdoes.com/archives/lib/ionic/css/ionic.css" rel="stylesheet""http://www.webdoes.com/archives/css/style.css" > <!-- IF using Sass (run gulp sass first),then uncomment below and remove the CSS includes above <link href="http://www.webdoes.com/archives/css/ionic.app.css" rel="stylesheet"> --> <!-- ionic/angularjs js --> <script src="http://www.webdoes.com/archives/lib/ionic/js/ionic.bundle.js"></script> <!-- cordova script (this will be a 404 during development) --> "http://www.webdoes.com/archives/cordova.js"></script> <!-- your app's js --> "http://www.webdoes.com/archives/js/app.js"></script> </head> <body ng-app="app" ng-controller="Metro" animation="slide-left-right-ios7"<ion-header-bar class="bar-dark"<h1 "title">{{title}}</h1> </ion-header-bar> <ion-content scroll="false"<div id="canvas" style="width: 100%; height: 100%;"></div> </ion-content> </body> "http://www.webdoes.com/archives/lib/qunee/qunee-min.js"</html>

index.html结构

首先看index.html,是主页面,里面引入了angularjs, cordova等js支持,此外还有app.js,controllers.js,services.js三个文件,这三个文件构建了app的应用逻辑,app是主程序,包含一些设置和启动脚本,services是数据支持部分,也就是model部分,用于提供数据的增删改查操作,controllers用于控制,包含业务逻辑控制代码

先在桌面环境下测试,Chrome运行正常,然后编译成各种移动平台版本,这里以android版本为例
ionic start q-metro
cd q-metro
ionic platform add android
ionic build android
ionic run android
如果要在虚拟机中测试,可以改用
ionic emulate android
ionic支持多种移动平台,如果希望创建ios可以将”android”改成”ios” 下面是android设备上真机运行界面如下:

给大家看看一个简单的demo的效果

源码如下也很简单,供大家学习:

index.html如下:

<html "ionicApp"<title>Ionic-AngularJS Kitchen Sink</title> <!--<link href="http://code.ionicframework.com/1.0.0-beta.1/css/ionic.min.css" rel="stylesheet">--> <!--<script src="http://code.ionicframework.com/1.0.0-beta.1/js/ionic.bundle.min.js"></script>--> "http://www.webdoes.com/archives/lib/ionic/css/ionic.beta.min.css" "http://www.webdoes.com/archives/lib/ionic/js/ionic.bundle.beta.min.js"<style> .Box {height:300px;padding: 10px} </style> "AppCtrl"<ion-nav-bar "nav-title-slide-ios7 bar-positive"<ion-nav-back-button "button-icon ion-arrow-left-c"</ion-nav-back-button> </ion-nav-bar> <ion-nav-view "slide-left-right"></ion-nav-view> "menu.html" type="text/ng-template"> <ion-side-menus> <ion-side-menu side="left"> <ion-header-bar class="bar-positive"> <h1 "title">Side Menu</h1> </ion-header-bar> <ion-content> <ul "list"> <a href="http://www.webdoes.com/archives/609.html#/menu/tab/buttons" "item" menu-toggle="left">问答服务</a> <!--<a href="http://www.webdoes.com/archives/609.html#/menu/keyboard" "left">Keyboard Input Types</a>--> <!--<a href="http://www.webdoes.com/archives/609.html#/menu/slideBox" Slide Box</a>--> <a href="http://www.webdoes.com/archives/609.html#/menu/about" About</a> </ul> </ion-content> </ion-side-menu> <ion-side-menu-content> <ion-nav-view name="menuContent"></ion-nav-view> </ion-side-menu-content> </ion-side-menus> </script> "tabs.html" > <ion-nav-bar "bar-positive"> <ion-nav-back-button "button-icon ion-arrow-left-c"> </ion-nav-back-button> <ion-nav-buttons side="left"> <button "button button-icon button-clear ion-navicon" ng-click="toggleLeft()"></button> </ion-nav-buttons> <ion-nav-buttons side="right"> <button "button button-icon button-clear ion-compose" ng-click="modal.show()"></button> </ion-nav-buttons> </ion-nav-bar> <ion-tabs "tabs-icon-top tabs-positive"> <ion-tab title="问答" icon="ion-pricetag" href="http://www.webdoes.com/archives/609.html#/menu/tab/buttons"> <ion-nav-view name="buttons-tab"></ion-nav-view> </ion-tab> <ion-tab title="日记" icon="ion-clipboard" href="http://www.webdoes.com/archives/609.html#/menu/tab/list"> <ion-nav-view name="list-tab"></ion-nav-view> </ion-tab> <ion-tab title="健康汇" icon="ion-settings" href="http://www.webdoes.com/archives/609.html#/menu/tab/form"> <ion-nav-view name="form-tab"></ion-nav-view> </ion-tab> </ion-tabs> "buttons.html" > <ion-view title="大咖问答"> <ion-content "padding"> <div "head" style="background-image: url(img/headImg.jpg);background-size: cover;position:relative;height: 120px;"> </div> <div "item item-divider"> 问答集锦 </div> <ion-list> <ion-item ng-repeat="testItem in testItems" item="testItem" href="http://www.webdoes.com/archives/609.html#/menu/tab/testItem" data-id="{{testItem.id}}"> 问题标题 {{ testItem.title }} </ion-item> </ion-list> </ion-content> </ion-view> "item.html" "Item"> <ion-content "padding"> <p>内容暂时没提供</p> </ion-content> </ion-view> "testItem.html" "testItem"> <ion-content "list.html" "日记列表"> <ion-content> <ion-list show-delete="data.showDelete" on-"onItemDelete(item)" option-buttons="itemButtons"> <div "list"> <!--<div "item item-divider">--> <ion-item ng-repeat="item in items" item="item" href="http://www.webdoes.com/archives/609.html#/menu/tab/item"> Item {{ item.id }} </ion-item> </div> </ion-list> </ion-content> </ion-view> "form.html" "健康专栏"> <ion-content "padding"> 开发中,尽请期待... <br> </ion-content> </ion-view> "slideBox.html" > <ion-view> <ion-header-bar "bar-positive"> <button "toggleLeft()"></button> <h1 Box</h1> </ion-header-bar> <ion-content> <ion-slide-Box> <ion-slide> <div "Box"> <h2>Box #1</h2> <p>Content goes here</p> </div> </ion-slide> <ion-slide> <div 2</h2> <p>3</h2> <p>Content goes here</p> </div> </ion-slide> </ion-slide-Box> </ion-content> </ion-view> "keyboard.html" Input</h1> </ion-header-bar> <ion-content "list"> <label "item item-divider"> Input types for popup keyboard </label> <label "item item-input"> <span "input-label">Text</span> <input type="text" ng-model="user.username"> </label> <label Password</span> <input type="password" ng-model="user.password"> </label> <label Email</span> <input type="email"> </label> <label Tel</span> <input type="tel"> </label> <label Number</span> <input type="number"> </label> <label Date</span> <input type="date"> </label> <label Month</span> <input type="month"> </label> </div> </ion-content> </ion-view> "about.html" About</h1> </ion-header-bar> <ion-content "card"> <div "item"> <h3>本测试demo由徐杰开发设计,仅供参考</h3> <p><a href="http://www.webdoes.com" target="_blank">联系他</a></p> </div> </div> </ion-content> </ion-view> "modal.html" > <div "modal"> <ion-header-bar "bar bar-header bar-positive"> <h1 "title">咨询</h1> <button "button button-clear button-primary" ng-click="modal.hide()">取消</button> </ion-header-bar> <ion-content "input-label">标题</span> <input type="text"> </label> <label "input-label">内容</span> <textarea rows="4"></textarea> </label> </div> <button "button icon icon-right ion-arrow-right-c button-balanced button-block">提交</button> </ion-content> </div>  核心代码app.js如下:

angular.module('ionicApp', ['ionic']) .config(function ($stateProvider, $urlRouterProvider) { $stateProvider .state('menu', { url: "/menu", abstract: true, templateUrl: "menu.html", controller: 'MenuCtrl' }) .state('menu.tabs',0)">"/tab", views: { 'menuContent' :{ templateUrl: "tabs.html" } } }) .state('menu.tabs.buttons',0)">"/buttons",0)">'buttons-tab': { templateUrl: "buttons.html",0)">'ButtonsTabCtrl' } } }) .state('menu.tabs.list',0)">"/list",0)">'list-tab': { templateUrl: "list.html",0)">'ListCtrl' } } }) .state('menu.tabs.item',0)">"/item",0)">"item.html" } } }) .state('menu.tabs.testItem',0)">"/testItem",0)">"testItem.html" } } }) .state('menu.tabs.form',0)">"/form",0)">'form-tab': { templateUrl: "form.html" } } }) .state('menu.keyboard',0)">"/keyboard",0)">'menuContent': { templateUrl: "keyboard.html" } } }) .state('menu.slideBox',0)">"/slideBox",0)">"slideBox.html",0)">'SlideBoxCtrl' } } }) .state('menu.about',0)">"/about",0)">"about.html" } } }); $urlRouterProvider.otherwise("menu/tab/buttons"); }) .controller('ListCtrl',139)">function ($scope) { $scope.data = { showDelete: false }; $scope.itemButtons = [ { text: 'Delete', type: 'button-assertive', onTap: function (item) { alert('Delete Item: ' + item.id + ' ?'); } } ]; $scope.onItemDelete = function (item) { $scope.items.splice($scope.items.indexOf(item), 1); }; $scope.items = [ { id: 1, title:'慢性鼻炎怎么预防?' }, { id: 2,0)">'高血压如何预防?' },0)">3,0)">'冠心病如何有效治疗?' },0)">4,0)">'高血压如何预防?' } ]; }) .controller('ButtonsTabCtrl',139)">function ($scope, $ionicPopup, $ionicActionSheet, $ionicModal) { $scope.showPopup = function () { $ionicPopup.alert({ title: 'Popup', content: 'This is ionic popup alert!' }); }; $scope.showActionsheet = function () { $ionicActionSheet.show({ titleText: 'Ionic ActionSheet', buttons: [ { text: 'Facebook' }, { text: 'Twitter' }, ], destructiveText:  cancelText: 'Cancel', cancel: function () { console.log('CANCELLED'); }, buttonClicked: function (index) { console.log('BUTTON CLICKED', index); return true; }, destructiveButtonClicked: 'DESTRUCT'); true; } }); }; $scope.testItems = [ { id: '高血压如何预防?' } ]; $ionicModal.fromTemplateUrl('modal.html',139)">function (modal) { $scope.modal = modal; }, { animation: 'slide-in-up' }); }) .controller('SlideBoxCtrl',139)">function($scope, $ionicSlideBoxDelegate) { $scope.nextSlide = function() { $ionicSlideBoxDelegate.next(); } }) .controller('MenuCtrl', $ionicSideMenuDelegate, $ionicModal) { $scope.toggleLeft = function() { $ionicSideMenuDelegate.toggleLeft(); }; $ionicModal.fromTemplateUrl('AppCtrl',139)">function() { ionic.Platform.ready(function() { }); });

发布:

Now we can tell cordova to generate our release build:

$ cordova build--release android

在IOS中也是一样,不过IOS要打包成ipa,需要开发者账号,有兴趣朋友求提供下,谢谢!

相关文章

AngularJS 是一个JavaScript 框架。它可通过 注:建议把脚本放在 元素的底部。这会提高网页加载速度,因...
angluarjs中页面初始化的时候会出现语法{{}}在页面中问题,也即是页面闪烁问题。出现这个的原因是:由于...
AngularJS 通过被称为指令的新属性来扩展 HTML。AngularJS 指令AngularJS 指令是扩展的 HTML 属性,带有...
AngularJS 使用表达式把数据绑定到 HTML。AngularJS 表达式AngularJS 表达式写在双大括号内:{{ expres...
ng-repeat 指令可以完美的显示表格。在表格中显示数据 {{ x.Name }} {{ x.Country }} 使用 CSS 样式为了...
$http是 AngularJS 中的一个核心服务,用于读取远程服务器的数据。读取 JSON 文件下是存储在web服务器上...