友链
导航
These are the good times in your life,
so put on a smile and it'll be alright
友链
导航
$ cd myApp
$ ionic platform add ios
$ ionic build ios
$ ionic emulate ios
sass gem
,这里会用 libsass
!# 开启 sass 支持
$ ionic setup sass
$ ionic serve
$ cp /tmp/fontello-xxx app/www/lib/fontello app/www/lib/fontello/css $ ln -s fontello.css _fontello.scss app/www/lib/fontello/css $ sed -i '#../font/#../lib/fontello/font/#' fontello.css $ vi app/scss/ionic.app.scss # 在 @import ionic 之后 // import extend icons from fontello // @todo but fontello is not sass, need to update "path" once updated // ../font/ -> ../lib/fontello/font/ @import "www/lib/fontello/css/fontello"; #### 到此结束,以下是注释 #### # 必须 sed 替换 fontello 的路径,否则会找不到 # ionicon 由于是用 sass,它修改路径的做法是在 ionic.app.scss 中声明 // The path for our ionicons font files, relative to the built CSS in www/css $ionicons-font-path: "../lib/ionic/fonts" !default;
alias ionic="PROXY=http://proxy-mu.intel.com:911 ionic"
export http_proxy=http://proxy-mu.intel.com:911 export https_proxy=http://proxy-mu.intel.com:911
$q(function() {})
会出现 $q is not a function
的错误, 只能用 $q.defer()
的方法. AngularJS: API: $q$http
好像也不正常, 尝试在 $stateProvider
的 resolve
中使用, 结果返回疑似 response
对象, 而非 resolve
后的结果// Declare factory module.factory('Users', function(Restangular) { return Restangular.service('users'); }); // In your controller you inject Users Users.one(2).get() // GET to /users/2 Users.post({data}) // POST to /users // GET to /users Users.getList().then(function(users) { var user = users[0]; // user === {id: 1, name: "Tonto"} user.name = "Gonto"; // PUT to /users/1 user.put(); })
$http
请求默认 accept: 'application/json, text/plain, */*'
, 而 express 可用 res.format 来实现一个 controller 对 web/API 返回不同数据的功能 res.format({ text: function(){ res.send('hey'); }, html: function(){ res.send('hey'); }, json: function(){ res.send({ message: 'hey' }); } });
<script type=“text/ng-template” id=“page-name”>
will add the template to the template cache, and save us the requestui-sref
而非 href
<ion-tabs>
布局时, 每个 <ion-tab>
中都要是一个有 name 的 <ion-nav-view
name=“tab-foo”>
<ion-tabs>
在进入 tab 的深层页面隐藏 tab-bar 可使用 ng-class=“{'tabs-item-hide': notFrontPage()}”
<meta name="apple-mobile-web-app-capable" content="yes"/>
<ion-header-bar class="bar-positive"> ... </ion-header-bar> <!-- 在 header 和 content 间加一个 loading-bar,在 isLoading 时显示 --> <div class="bar bar-loading bar-assertive" ng-if="data.isLoading"> Loading... </div> <!-- content 在 isLoading 时增加 class --> <ion-content ng-class="{'has-loading': data.isLoading}"> ... </ion-content>
.has-header.has-loading { /* 44px (header) + 24px(loading bar) */ top: 68px; }
ionic-cli
v1.2.5 升级 ionic 的 ionic lib update
命令是坏的bower install some-package
会同时把 bower.json
中的其他 packages 都 install 了,不该这样,但原因没找到。如果要 干净地 用 bower install
,可以先删除 bower.json
ng-repeat row
、ng-repeat col
。参考:angularjs - how to split the ng-repeat data with three columns using bootstrap - Stack Overflowng-pattern
做验证(像验证 email 时),会出现一输入就报错的问题。一般有两种方法解决ng-model-options=“{ updateOn: 'blur' }”
<p ng-show=“form.field.$touched && form.field.$invalid”>Error</p>
GA 的用法见 ga
angular.module('myApp', [ 'angulartics', 'angulartics.google.analytics' ]);
... ga('create', 'UA-XXXXXXXX-X', 'none'); // 'none' while you are working on localhost ga('send', 'pageview'); // 删除这行! </script>
Ionic(ion-nav-view
) uses the AngularUI Router module so app interfaces can be organized into various “states”.
ion-nav-view
is equivalent to ui-view
. On top of that, ion-nav-view
provides for animations, history, and more.
<!-- in index.html --> <body ng-controller="MainCtrl"> <section ui-view></section> </body>
// in app-states.js (or whatever you want to name it) $stateProvider.state('contacts', { template: '<h1>My Contacts</h1>' })
When a state is activated, its templates are automatically inserted into the ui-view
of its parent state's template.
There are three main ways to activate a state:
$stateProvider.state('contacts', { // 可以返回内容 template: '<h1>My Contacts</h1>' // or templateProvider: function ($timeout, $stateParams) { return $timeout(function () { return '<h1>' + $stateParams.contactId + '</h1>' }, 100); } // 也可以返回模板 URL templateUrl: 'contacts.html' // or templateUrl: function ($stateParams){ return '/partials/contacts.' + $stateParams.filterBy + '.html'; } })
$stateProvider.state('contacts', { template: ..., // define a controller controller: function($scope){ $scope.title = 'My Contacts'; } // a defined controller controller: 'ContactsCtrl' // controllerAs syntax controller: 'ContactsCtrl as contact' // dynamically return a controller function or string controllerProvider: function($stateParams) { var ctrlName = $stateParams.type + "Controller"; return ctrlName; } })
另外有一种写法, 是通过 resolve
(一个 key
和 factory
的 mapping) 加载若干依赖/调用若干服务 (typical usage 是 factory
用 promise). 而 controller
只是做一个 “依赖到 $scope 的 mapping”. 详见 wiki#resolve. 很好用
示例如下:
$stateProvider.state('myState', { resolve:{ // Example using function with simple return value. // Since it's not a promise, it resolves immediately. simpleObj: function(){ return {value: 'simple!'}; }, // Example using function with returned promise. // This is the typical use case of resolve. // You need to inject any services that you are // using, e.g. $http in this example promiseObj: function($http){ // $http returns a promise for the url data return $http({method: 'GET', url: '/someUrl'}); }, // Another promise example. If you need to do some // processing of the result, use .then, and your // promise is chained in for free. This is another // typical use case of resolve. promiseObj2: function($http){ return $http({method: 'GET', url: '/someUrl'}) .then (function (data) { return doSomeStuffFirst(data); }); }, // Example using a service by name as string. // This would look for a 'translations' service // within the module and return it. // Note: The service could return a promise and // it would work just like the example above translations: "translations", // Example showing injection of service into // resolve function. Service then returns a // promise. Tip: Inject $stateParams to get // access to url parameters. translations2: function(translations, $stateParams){ // Assume that getLang is a service method // that uses $http to fetch some translations. // Also assume our url was "/:lang/home". return translations.getLang($stateParams.lang); }, // Example showing returning of custom made promise greeting: function($q, $timeout){ var deferred = $q.defer(); $timeout(function() { deferred.resolve('Hello!'); }, 1000); return deferred.promise; } }, // The controller waits for every one of the above items to be // completely resolved before instantiation. For example, the // controller will not instantiate until promiseObj's promise has // been resolved. Then those objects are injected into the controller // and available for use. controller: function($scope, simpleObj, promiseObj, promiseObj2, translations, translations2, greeting){ $scope.simple = simpleObj.value; // You can be sure that promiseObj is ready to use! $scope.items = promiseObj.items; $scope.items = promiseObj2.items; $scope.title = translations.getLang("english").title; $scope.title = translations2.title; $scope.greeting = greeting; } })
// Example shows an object-based state and a string-based state var contacts = { name: 'contacts', templateUrl: 'contacts.html', data: { customData1: 5, customData2: "blue" } } $stateProvider .state(contacts) .state('contacts.list', { templateUrl: 'contacts.list.html', data: { customData1: 44, customData2: "red" } }) // In any controller you could access the data like this: function Ctrl($state){ console.log($state.current.data.customData1) // outputs 5; console.log($state.current.data.customData2) // outputs "blue"; }
onEnter and onExit callbacks
$stateChangeStart
fired when the transition begins.$stateNotFound
- v0.3.0 - fired when a requested state cannot be found using the provided state name during transition. $stateChangeSuccess
- fired once the state transition is complete.$stateChangeError
- fired when an error occurs during transition.$viewContentLoading
- fired once the view begins loading, before the DOM is rendered. The $scope
broadcasts the event.$viewContentLoaded
- fired once the view is loaded, after the DOM is rendered. The $scope
of the view emits the event.CSS Components - Ionic Framework
Javascript - Extend Ionic even further with the power of AngularJS - Ionic Framework
How to Learn AngularJS - Your AngularJS Sherpa | ng-newsletter
basics of Angular can be broken down into 5 major components:
ng-
tags and attributes are Angular provided directives.ngClick
in js and ng-click
in HTML refer to the same thing, the idea is that it makes each code look better in context.<span my-directive></span>
<span class="my-directive: expression;"></span>
<my-directive></my-directive>
<!-- directive: my-directive expression -->
DOMContentLoaded
event (this means that Angular will run when the page is done loading).ngApp
directive. Angular will bind our application to the element where it finds the ngApp
directive. ngApp
. ngApp
对应一个 angular.module()
angular.module()
有 setter/getter 两种用法angular.module('myApp', []);
angular.module('myApp');
$scope variable
可实现双向绑定 angular.module('myApp', []) .run(function($rootScope) { $rootScope.user = { email: 'ari@fullstack.io' }; $rootScope.message = "Welcome back"; }); // html // <input type="text" ng-model="message" placeholder="Enter a message" /> // <h3>{{ message }} {{ user.email }}</h3>
module.run()
的 cb 设置了 $rootScope angular.module('myApp', []) .run(function($rootScope) { // ... }
<body ng-app='myApp'> <!-- We have access to the $rootScope here --> <h1>Welcome back {{ user.name }}</h1> <div ng-controller='HomeController'> <!-- in here, the $scope object of the HomeController will be used, but we still have access to the $rootScope object --> The HomeController thinks your name is {{ user.name }}, while the $rootScope thinks it's {{ $parent.user.name }}. </div> </body>
angular.module('myApp', []) .run(function($rootScope) { $rootScope.user = { name: 'Ari' }; }) .controller('HomeController', function($scope) { $scope.user = { name: 'Nate' }; });
Welcome back Ari The HomeController thinks your name is Nate, while the $rootScope thinks it's Ari.
$http
!XMLHttpRequest
(also known as XHR
, which is how you perform AJAX
) called $http
.promise .then(function(data) { // Called when no errors have occurred with data }) .catch(function(err) { // Called when an error has occurred }) .finally(function(data) { // Called always, regardless of the output result })
angular.module('myApp', []) .controller('HomeController', function($scope, $q) { // We have the $scope object and the $q object // available in here });
.controller()
设置的 function()
并不是 node.js 常用的 cb 模式, 而就是在定义一个 controller, function()
的参数描述了 DI 关系, 而不是特定的 cb 的参数顺序// say we have some services... angular.module('fullstack.services', []) // some code that defines services here .service('WeatherService', function() { // define the weather service here }); ); // and we want to use those services in our controllers angular.module('fullstack.controllers', ['fullstack.services']) // now we have WeatherService available );
$scope
, $q
是 Angular built-ins so they’re already included// 普通 annotation, 不能被 minify .controller('HomeController', function($q, $scope) { // inline annotation, 可被 minify .controller('HomeController', ['$scope', '$q', function($scope, $q) {
annote
/DI
module, controller annote
/DI
service