学习Ionic之前为什么要学Angularjs,Ionic和Angularjs学习的学是什么部首关系

使用ionic+angular+phonegap开发APP入门 - 为程序员服务
使用ionic+angular+phonegap开发APP入门
67176 阅读
有时候朋友问我是做什么的?我说以前是用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的文档,
Ionic 是一个用HTML, CSS 跟JS 开发的一个用于移动设备的web app 开发框架,采用 Sass与AngularJS 开发。
(2) 看一遍phonegap的文档;目前phonegap又取名为cordova;有些常用的命令总结如下:
项目例子:http://my.oschina.net/nosand/blog/294011
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文件
open .bash_profile
#设置相关的Path,mac os x下增加类似下面的内容
export JAVA_HOME=
/usr/libexec/java_home -v 1.8
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 /getting-started/
创建ionic项目q-metro
使用下面的命令创建一个新的项目
ionic start q-metro
初始目录结构如下
&!DOCTYPE html&
&meta charset="utf-8"&
&meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"&
&title&&/title&
&link href="/archives/lib/ionic/css/ionic.css" rel="stylesheet"&
&link href="/archives/css/style.css" rel="stylesheet"&
&!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
&link href="/archives/css/ionic.app.css" rel="stylesheet"&
&!-- ionic/angularjs js --&
&script src="/archives/lib/ionic/js/ionic.bundle.js"&&/script&
&!-- cordova script (this will be a 404 during development) --&
&script src="/archives/cordova.js"&&/script&
&!-- your app's js --&
&script src="/archives/js/app.js"&&/script&
&body ng-app="app" ng-controller="Metro" animation="slide-left-right-ios7"&
&ion-header-bar class="bar-dark"&
&h1 class="title"&{{title}}&/h1&
&/ion-header-bar&
&ion-content scroll="false"&
&div id="canvas" style="width: 100%; height: 100%;"&&/div&
&/ion-content&
&script src="/archives/lib/qunee/qunee-min.js"&&/script&
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如下:
&!DOCTYPE html&
&html ng-app="ionicApp"&
&meta charset="utf-8"&
&meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"&
&title&Ionic-AngularJS Kitchen Sink&/title&
&!--&link href="/1.0.0-beta.1/css/ionic.min.css" rel="stylesheet"&--&
&!--&script src="/1.0.0-beta.1/js/ionic.bundle.min.js"&&/script&--&
&link href="/archives/lib/ionic/css/ionic.beta.min.css" rel="stylesheet"&
&script src="/archives/lib/ionic/js/ionic.bundle.beta.min.js"&&/script&
&script src="/archives/js/app.js"&&/script&
.box {height:300padding: 10px}
&body ng-controller="AppCtrl"&
&ion-nav-bar class="nav-title-slide-ios7 bar-positive"&
&ion-nav-back-button class="button-icon ion-arrow-left-c"&
&/ion-nav-back-button&
&/ion-nav-bar&
&ion-nav-view animation="slide-left-right"&&/ion-nav-view&
&script id="menu.html" type="text/ng-template"&
&ion-side-menus&
&ion-side-menu side="left"&
&ion-header-bar class="bar-positive"&
&h1 class="title"&Side Menu&/h1&
&/ion-header-bar&
&ion-content&
&ul class="list"&
&a href="/archives/609.html#/menu/tab/buttons" class="item" menu-toggle="left"&问答服务&/a&
&!--&a href="/archives/609.html#/menu/keyboard" class="item" menu-toggle="left"&Keyboard Input Types&/a&--&
&!--&a href="/archives/609.html#/menu/slidebox" class="item" menu-toggle="left"&Slide Box&/a&--&
&a href="/archives/609.html#/menu/about" class="item" menu-toggle="left"&About&/a&
&/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 id="tabs.html" type="text/ng-template"&
&ion-nav-bar class="bar-positive"&
&ion-nav-back-button class="button-icon ion-arrow-left-c"&
&/ion-nav-back-button&
&ion-nav-buttons side="left"&
&button class="button button-icon button-clear ion-navicon" ng-click="toggleLeft()"&&/button&
&/ion-nav-buttons&
&ion-nav-buttons side="right"&
&button class="button button-icon button-clear ion-compose" ng-click="modal.show()"&&/button&
&/ion-nav-buttons&
&/ion-nav-bar&
&ion-tabs class="tabs-icon-top tabs-positive"&
&ion-tab title="问答" icon="ion-pricetag" href="/archives/609.html#/menu/tab/buttons"&
&ion-nav-view name="buttons-tab"&&/ion-nav-view&
&/ion-tab&
&ion-tab title="日记" icon="ion-clipboard" href="/archives/609.html#/menu/tab/list"&
&ion-nav-view name="list-tab"&&/ion-nav-view&
&/ion-tab&
&ion-tab title="健康汇" icon="ion-settings" href="/archives/609.html#/menu/tab/form"&
&ion-nav-view name="form-tab"&&/ion-nav-view&
&/ion-tab&
&/ion-tabs&
&script id="buttons.html" type="text/ng-template"&
&ion-view title="大咖问答"&
&ion-content class="padding"&
&div class="head" style="background-image: url(img/headImg.jpg);background-size:position:height: 120"&
&div class="item item-divider"&
&ion-list&
&ion-item ng-repeat="testItem in testItems" item="testItem" href="/archives/609.html#/menu/tab/testItem" data-id="{{testItem.id}}"&
问题标题: {{ testItem.title }}
&/ion-item&
&/ion-list&
&/ion-content&
&/ion-view&
&script id="item.html" type="text/ng-template"&
&ion-view title="Item"&
&ion-content class="padding"&
&p&内容暂时没提供&/p&
&/ion-content&
&/ion-view&
&script id="testItem.html" type="text/ng-template"&
&ion-view title="testItem"&
&ion-content class="padding"&
&p&内容暂时没提供&/p&
&/ion-content&
&/ion-view&
&script id="list.html" type="text/ng-template"&
&ion-view title="日记列表"&
&ion-content&
&ion-list show-delete="data.showDelete" on-delete="onItemDelete(item)" option-buttons="itemButtons"&
&div class="list"&
&!--&div class="item item-divider"&--&
&ion-item ng-repeat="item in items" item="item" href="/archives/609.html#/menu/tab/item"&
Item {{ item.id }}
&/ion-item&
&/ion-list&
&/ion-content&
&/ion-view&
&script id="form.html" type="text/ng-template"&
&ion-view title="健康专栏"&
&ion-content class="padding"&
开发中,尽请期待...
&/ion-content&
&/ion-view&
&script id="slidebox.html" type="text/ng-template"&
&ion-view&
&ion-header-bar class="bar-positive"&
&button class="button button-icon button-clear ion-navicon" ng-click="toggleLeft()"&&/button&
&h1 class="title"&Slide Box&/h1&
&/ion-header-bar&
&ion-content&
&ion-slide-box&
&ion-slide&
&div class="box"&
&h2&Box #1&/h2&
&p&Content goes here&/p&
&/ion-slide&
&ion-slide&
&div class="box"&
&h2&Box #2&/h2&
&p&Content goes here&/p&
&/ion-slide&
&ion-slide&
&div class="box"&
&h2&Box #3&/h2&
&p&Content goes here&/p&
&/ion-slide&
&/ion-slide-box&
&/ion-content&
&/ion-view&
&script id="keyboard.html" type="text/ng-template"&
&ion-view&
&ion-header-bar class="bar-positive"&
&button class="button button-icon button-clear ion-navicon" ng-click="toggleLeft()"&&/button&
&h1 class="title"&Keyboard Input&/h1&
&/ion-header-bar&
&ion-content class="padding"&
&div class="list"&
&label class="item item-divider"&
Input types for popup keyboard
&label class="item item-input"&
&span class="input-label"&Text&/span&
&input type="text" ng-model="user.username"&
&label class="item item-input"&
&span class="input-label"&Password&/span&
&input type="password" ng-model="user.password"&
&label class="item item-input"&
&span class="input-label"&Email&/span&
&input type="email"&
&label class="item item-input"&
&span class="input-label"&Tel&/span&
&input type="tel"&
&label class="item item-input"&
&span class="input-label"&Number&/span&
&input type="number"&
&label class="item item-input"&
&span class="input-label"&Date&/span&
&input type="date"&
&label class="item item-input"&
&span class="input-label"&Month&/span&
&input type="month"&
&/ion-content&
&/ion-view&
&script id="about.html" type="text/ng-template"&
&ion-view&
&ion-header-bar class="bar-positive"&
&button class="button button-icon button-clear ion-navicon" ng-click="toggleLeft()"&&/button&
&h1 class="title"&About&/h1&
&/ion-header-bar&
&ion-content class="padding"&
&div class="card"&
&div class="item"&
&h3&本测试demo由徐杰开发设计,仅供参考&/h3&
&p&&a href="" target="_blank"&联系他&/a&&/p&
&/ion-content&
&/ion-view&
&script id="modal.html" type="text/ng-template"&
&div class="modal"&
&ion-header-bar class="bar bar-header bar-positive"&
&h1 class="title"&咨询&/h1&
&button class="button button-clear button-primary" ng-click="modal.hide()"&取消&/button&
&/ion-header-bar&
&ion-content class="padding"&
&div class="list"&
&label class="item item-input"&
&span class="input-label"&标题&/span&
&input type="text"&
&label class="item item-input"&
&span class="input-label"&内容&/span&
&textarea rows="4"&&/textarea&
&button class="button icon icon-right ion-arrow-right-c button-balanced button-block"&提交&/button&
&/ion-content&
核心代码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', {
url: "/tab",
'menuContent' :{
templateUrl: "tabs.html"
.state('menu.tabs.buttons', {
url: "/buttons",
'buttons-tab': {
templateUrl: "buttons.html",
controller: 'ButtonsTabCtrl'
.state('menu.tabs.list', {
url: "/list",
'list-tab': {
templateUrl: "list.html",
controller: 'ListCtrl'
.state('menu.tabs.item', {
url: "/item",
'list-tab': {
templateUrl: "item.html"
.state('menu.tabs.testItem', {
url: "/testItem",
'buttons-tab': {
templateUrl: "testItem.html"
.state('menu.tabs.form', {
url: "/form",
'form-tab': {
templateUrl: "form.html"
.state('menu.keyboard', {
url: "/keyboard",
'menuContent': {
templateUrl: "keyboard.html"
.state('menu.slidebox', {
url: "/slidebox",
'menuContent': {
templateUrl: "slidebox.html",
controller: 'SlideboxCtrl'
.state('menu.about', {
url: "/about",
'menuContent': {
templateUrl: "about.html"
$urlRouterProvider.otherwise("menu/tab/buttons");
.controller('ListCtrl', 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 = [
title:'慢性鼻炎怎么预防?'
title:'高血压如何预防?'
title:'冠心病如何有效治疗?'
title:'高血压如何预防?'
.controller('ButtonsTabCtrl', 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: 'Delete',
cancelText: 'Cancel',
cancel: function () {
console.log('CANCELLED');
buttonClicked: function (index) {
console.log('BUTTON CLICKED', index);
destructiveButtonClicked: function () {
console.log('DESTRUCT');
$scope.testItems = [
title:'慢性鼻炎怎么预防?'
title:'高血压如何预防?'
title:'冠心病如何有效治疗?'
title:'高血压如何预防?'
$ionicModal.fromTemplateUrl('modal.html', function (modal) {
$scope.modal =
animation: 'slide-in-up'
.controller('SlideboxCtrl', function($scope, $ionicSlideBoxDelegate) {
$scope.nextSlide = function() {
$ionicSlideBoxDelegate.next();
.controller('MenuCtrl', function($scope, $ionicSideMenuDelegate, $ionicModal) {
$scope.toggleLeft = function() {
$ionicSideMenuDelegate.toggleLeft();
$ionicModal.fromTemplateUrl('modal.html', function (modal) {
$scope.modal =
animation: 'slide-in-up'
.controller('AppCtrl', function() {
ionic.Platform.ready(function() {
Now we can tell cordova to generate our release build:
$ cordova build --release android
在IOS中也是一样,不过IOS要打包成ipa,需要开发者账号,有兴趣朋友求提供下,谢谢!
Del.icio.us
StumbleUpon
You might be interested in this:
Copyright (C)
], All Right Reserved. 2015.
紧随web潮流
原文地址:, 感谢原作者分享。
您可能感兴趣的代码  Angular js是一个Web应用框架,它极其流行,已经成为目前使用最广泛的Javascript工具之一。Ionic基于AngularJS构建而成,所以学习一些AngularJS的知识很有必要。Ionic并没有独立开发一套完整的Web应用框架,而是对AngularJS进行了扩展,给它添加了大量界面组件和其他的移动端友好的特性。
  本篇文章会带你了解AngularJS的核心知识并介绍一些基础知识。我们学会控制器,顾名思义,它会控制(control)你的数据。接着我们介绍作用于,它会连接控制器和用户界面,后者被称为视图(view)。仔细观察视图,你会看到他们是如何通过模板和作用域来创建交互视觉效果的。在这个过程中,我们还会学习其它特性,比如如何使用过滤器来转换数据、如何构建并使用指令来增强现有的HTML元素,以及如何从外部数据源中加载并保存应用数据。
  现在我们来看一个bootstrap+AngularJS开发的一个小应用,方便我们了解AngularJS。你可以草丛GitHub上查看完整的项目代码。如果你想看最终的效果,可以访问
1.视图和模板:描述内容
  AngularJS和HTML关系密切,尤其是在你创建模板的时候。模板是一块HTML内容,可以再需要的时候载入应用。AngularJS向HTML中加入了许多新特性并扩充了HTML的语义。视图会使用模板来展示数据。视图一定会有一个模板(就是HTML标签),还会有模板需要用到数据。视图会把模板转换成用户最终看到的视觉效果,也就是说,它会基于数据修改模板。下面我们来看一段模板
&ul class="list-group"&
&li class="list-group-item" ng-repeat="note in notes" ng-click="displayNote($index)" ng-class="{active:note.id==content.id}"&
{{note.title}}&br/&
&small&{{note.date|date:'short'}}&/small&
  这段模板展示的只是&ul&中的一个&li&元素,它包含多个被称为Angular指令的属性。指令会修改包含它的元素行为。在本例中,ng-Repeat会遍历一个Javascript对象或者数组,并为每个元素创建一个&li&元素。ng-click类似Javascript的onClick时间处理器,单击时会调用displayNote()函数。这个模板被渲染时会为notes数组中的每个元素创建一个列表元素。
  双花括号({{}})表示某些数据会被展示在这里,这种思想被称为数据绑定,这种语法叫做表达式花括号中的所有内容都是表达式,Angular会用当前模型的数据对表达式求值。因此,note.title的内容会被插入到&li&元素中花括号包裹的位置。模板就是带有指令或表达式的HTML。视图会获取数据并使用数据中的值来对模板进行渲染。假设notes数组中有5个笔记,&ul&元素会包含5个列表元素,如图。
  Angular有很多自带的指令,它们都以ng开头。有些用来修改显示样式(如ng-show、ng-class),有些用于表单(如ng-model、ng-Form),有些用于监听点击等各种事件(如ng-click、ng-mouseover)。Angular还有许多作用在原生HTML元素上的指令,提供一些HTML没有的功能,这些元素包括输入框、文本区域和锚点。举个例子,Angular可以给&input type="text"&元素添加额外的属性,让它支持自定义验证。完整的列表请查阅Angular官方文档。
2.控制器、模型、和作用域:管理数据和逻辑
  控制器是附加在文档对象模型(DOM)节点上的函数,用来驱动你的应用逻辑。在Javascript中,控制器就是一个函数,用来和作用域通信并响应时间。
  作用域可以理解为在控制器和视图之间共享的一个上下文。可以把它看做控制器和界面的桥梁,作用域在控制器中更新时也会更新视图。作用域有两个核心角色:存储数据并允许控制器的方法访问数据。存储在作用域中的数据被称为模型。模型可以是任意Javascript值(同城是数组或者对象,也可以是简单的数据或者字符串),你可以把它存储在作用域中,然后通过作用域共享个控制器和视图。我们来看一个例子,它会把上图的视图和模板结合起来:
angular.module("App")
.controller('Controller',function($scope){
$scope.notes=[
{id:1,title:'Note 1',date:new Date()}
{id:2,title:'Note 2',date:new Date()}
$scope.getNote=function(index){
$scope.content=$scope.notes[$index];
  这个控制器会使用一个数组中的元素来设置notes模型,后者存储在一个特殊的$scope对象中。这个对象是Angular提供的,每个作用域都有,你可以存储数据并在控制器和视图(也就是模型)中共享数据。视图会使用ng-repeat在列表中展示笔记数组。getNote()方法可以帮你声明哪些笔记需要存储在content模型中。视图可以调用这个方法,因为它们在同一个作用域中。
  控制器中的所有内容都和应用的其他部分隔离,除了它自己的子作用域。这很重要,因为这可以限制代码和变量的可见性。对于一个新Angular开发这来说,常见的挑战就是访问不同作用域中的内容,默认情况下是不可能实现的。
  Angular的作用域是有层级结构的,作用域可以想DOM一样嵌套。实际上,作用域对应页面上的DOM结构。作用域可以通过附加实现只允许一个HTML元素及其它子元素访问,就像CSS类可以将目标样式应用在设置类的元素及子元素一样。
  当想进行跨作用域通信时,层级结构变得尤其重要,因为子作用域可以查看父作用域(就像Javascript的原型继承一样,如果你很熟悉的话)。Angular中的一些指令会创建子作用域,因此有时候不太好判断具体的作用域。如果你在子作用域中访问一个不存在的值,它实际上会在父作用域中寻找那个值,直到找到或者遍历完所有的父作用域。
  根作用域(通过特殊的$root Scope对象访问)是Angular创建的第一个作用域,是其它所有作用域的基础。这意味着你放在根作用域上的所有东西对其它作用域都是可见的,听起来似乎还不错,但最好不要这样做。需要保持作用域整洁和聚焦,而不是把所有东西都堆在根作用域里。Javascript的作用域就有这个问题,应用通常使用全局作用域来保存变量。假设你有一个名为id的值;如果你的子作用域也有一个id,就会出现冲突,你无法访问根作用域中的值。协同开发时这个问题会更加突出,因为开发同一个应用的人越多或者你使用的外部工具越多,那就越有可能出现命名冲突。
注意:控制器不是万能的
  有一些事实不应该在控制器中做的,因为它们会让你的代码更难维护和测试。最重要的是避免在控制器中进行DOM操作,假设你在构建一个幻灯片效果,控制器不应该改动DOM或者改变幻灯片的样式,因为这应该有自定义指令实现。你还应该避免在控制器中格式化或者过滤数据,可使用表单来做这些是。
3.Service:可重用的对象和方法
  Angular中有一个概念交service,它本质上就是一个javascript对象,可以在整个应用中共享。Angular默认提供了许多service,你可以创建自己的service。如果你已经尝试过Angular,那你肯定用过自带的service。
  $http是一个非常常见的service,Angular用它来操作HTTP请求。它有很多方法,比如get()、post()和其他的HTTP动作。service可以非常复杂(比如$http),也可以简单的只包含一些数据。
  service是有Angular延迟加载的,也就是说,它们只会在使用的时候才载入内存。它们还是单例的,如果你在一个地方改变了service的值,其它用到这个service的地方都会受影响。Ionic把许多特性写成了Angular的service,需要记住的是,控制器中包含的几乎所有的内容都是service。
4.双向数据绑定:在控制器和视图之间共享数据
  Angular最强大的特性之一就是双向数据绑定。你已经看到了视图如何把数据绑定到模板,其实反过来同样适用。视图可以改变作用域中的数据,数据会立刻更新到作用域并反应到控制器中。这在表单中尤其有用,用户向文本框中输入内容时,作用域中的值会同步更新。你不需要做任何特殊的事情来启动双向数据绑定&&她会自动实现。
结语:以上就是Angular的核心概念,这些背景知识已经足够你起步。
阅读(...) 评论()

我要回帖

更多关于 学习中偷学是什么 的文章

 

随机推荐