1:tab的路由導向問題
運用ion-tabs時,第一個ion-tabs標簽下的href功能會覆蓋掉路由中定義的默認路由(進入應用后直接加載href指向的組件)。
解決方法:多寫一個ion-tabs標簽,然后將href指向寫為空,這樣就直接加載了路由文件中路由為空的情況的組件,然后再講這個ion-tabs標簽隱藏起來。
2:tab導航位置在頁面頂部:
.config(function ($ionicConfigProvider) { $ionicConfigProvider.backButton.text(" ").previousTitleText(false); $ionicConfigProvider.backButton.icon('ion-ios-arrow-back'); //設置安卓和ios tabs切換的樣式 $ionicConfigProvider.platform.ios.tabs.style('standard'); $ionicConfigProvider.platform.ios.tabs.position('bottom'); $ionicConfigProvider.platform.android.tabs.style('standard'); $ionicConfigProvider.tabs.position('bottom');//為了將tab放這里,必須要配置 $ionicConfigProvider.platform.ios.views.transition('ios'); $ionicConfigProvider.platform.android.views.transition('android'); })
3:滾動區域設置:
設置scroll屬性值為true,ionic自帶的滾動在移動端會很流暢。而且可以配合下拉刷新和上拉加載使用
<ion-content scroll="true">
注意:如果ion-content下有一個大的容器,那么這個容器的高度一定不要設置高度為100%。不然內容超出頁面高度時無法滾動。
4:引用文件問題:
ionic.bundle.js is a concatenation of:
* ionic.js, angular.js, angular-animate.js,
* angular-sanitize.js, angular-ui-router.js,
* and ionic-angular.js
我們在引用了ionoc.bundle.js后就不需要引入其包含的js文件了。
5:swiper輪播圖傳入ng遍歷的數據時,無法滑動輪播圖的問題:
我們在初始化swiper對象時,要加入以下兩句代碼:
var swiper = new Swiper('.swiper-container', { pagination: '.swiper-pagination', paginationClickable: true, observer:true, // 修改swiper自己或子元素時,自動初始化swiper observeParents:true // 修改swiper的父元素時,自動初始化swiper });
注意:
如果使用上述方法后,頁面中的圖片無法自動滾動,這時候我們可以在異步獲取數據的success回調中直接初始化swiper。
6:下拉刷新和上拉加載:
刷新元素:
<ion-refresher pulling-text="下拉刷新" on-refresh="doRefresh()"></ion-refresher>
加載元素:
<ion-infinite-scroll ng-if="show" pulling-text="上拉加載" on-infinite="loadMore()" distance="1%"></ion-infinite-scroll >
刷新回調:
$scope.doRefresh = function() { $scope.begin = 1; //重置到第一頁 $scope.show = true; // 重置加載組件 geiRijiList() //這個函數是頁面中獲取數據的函數,需要自己定義 $scope.$broadcast('scroll.refreshComplete'); };
加載回調:
$scope.show = false; $scope.loadMore = function () { if($scope.show){ $scope.begin = $scope.begin + 1; //分頁加1 //這里使用定時器是為了緩存一下加載過程,防止加載過快 var timer = $timeout(function () { $http({ method : 'get', url : API_URL+"diary/getDiaryInfo", params : { 'stuId':stuId, 'userId': userId, 'begin':$scope.begin } }).success(function(json){ if(json.data.length == 0 || !json.data){ //獲取數據為空時,隱藏並return $scope.show = false; // 當下拉加載時,頁面中沒有數據時,沒有更多數據的提示消失 if($scope.rijiList.length == 0 || !$scope.rijiList){ $scope.noData = false; }else{ $scope.noData = true; } return }else if(json.data.length>0 && json.data.length<10){ // 當數據在10條以內 $scope.rijiList = $scope.rijiList.concat(json.data); $scope.show = false; $scope.noData = true; return }else{ //10條及以上 $scope.rijiList = $scope.rijiList.concat(json.data); } }).error(function(json){ //處理響應失敗 toaster.pop('warning', null, '網絡連接異常,請稍后再試!', null, 'trustedHtml'); }); $scope.$broadcast('scroll.infiniteScrollComplete'); $scope.$broadcast('scroll.refreshComplete'); $timeout.cancel(timer); return }, 1500) } }
注意:
1:上拉加載觸發的事件是根據其顯示的true或false來的,所以說我們在頁面加載時,就要將$scope.show = false。如果是true,頁面一加載就會觸發loadMore()。
2:$scope.show的值是在頁面第一次查詢數據后,根據值的長度設置的,如果超過10條(這里的10條是后台分頁數據每頁的數據個數),就將$scope.show設置為true,這里設置后不會直接調用loadMore()
3:上拉加載調取接口數據的時候可以設置一個settimeout,防止加載過快。
4:每次執行上拉加載都要使用concat()拼接數據。
5:如果上拉加載的數據長度在0~9之間,說明后面的頁數已經沒有數據了。這時我們將$scope.show的值設置為false,這樣的話就不會再調用loadMore()這個方法了。
7:ionic自定義的手勢事件:
ionic已經封裝了手勢事件,如tap,swipe等
8:解決AngularJS使用ng-bind-html會過濾html字符串中style屬性的問題
使用$sce.trustAsHtml()方法處理,這個方法只能對字符串進行處理。$sce要注入到controller里。
8:頁面傳參與路由傳參
頁面傳參:頁面中事件傳遞參數到對應的js中時,如果傳遞的值中含有特殊字符等,會報錯。
路由傳參:
1:在路由文件中,將被傳參的路由設置參數,如:
.state('proInfo',{
url:"/proInfo",
cache:'false',
params:{"data":null},
templateUrl: "templates/proInfo.html",
controller: 'proInfoCtrl'
})
2:在被傳參的controller中注入$stateParams,並用$stateParams.data接受參數對象
3:傳參頁面在路由跳轉事件時,加入如下參數變量(變量自定義,可多個):
$state.go('jiesong_info',{data:{"id":id}})
9:打包成原生應用后如何實現存儲圖片到相冊和分享至微信的功能。
1、保存到相冊:
$scope.save = function() { var photoPath = $(".swiper-slide-active img").attr("ng-src"); //這是圖片的路徑 var pictrueUrl = encodeURI(photoPath); function saveImageToPhone(url, success, error) { var canvas, context, imageDataUrl, imageData; var img = new Image(); img.crossOrigin = 'anonymous'; //當圖片是跨域請求時,需要加這句話 img.src = url; img.onload = function () { canvas = document.createElement('canvas'); canvas.width = img.width; canvas.height = img.height; context = canvas.getContext('2d'); context.drawImage(img, 0, 0); try { imageDataUrl = canvas.toDataURL('image/jpeg', 1.0); imageData = imageDataUrl.replace(/data:image\/jpeg;base64,/, ''); cordova.exec( success, error, 'Canvas2ImagePlugin', 'saveImageDataToLibrary', [imageData] ); } catch (e) { error(e.message); } }; try { img.src = url; } catch (e) { error(e.message); } } var success = function (msg) { toaster.pop('warning', null, '保存成功!', null, 'trustedHtml'); }; var error = function (err) { toaster.pop('warning', null, '保存失敗!', null, 'trustedHtml'); }; saveImageToPhone(photoPath, success, error); }
注意:當我們保存的圖片是跨域請求的圖片,我們需要加上img.crossOrigin = 'anonymous'這句代碼。打包的時候,安卓和ios還需要安裝一個插件:
cordova plugin add https://github.com/devgeeks/Canvas2ImagePlugin.git
2:分享至微信:
$scope.share = function(){ var photoPath = $(".swiper-slide-active img").attr("ng-src"); var hideSheet = $ionicActionSheet.show({ buttons: [ { text: '微信朋友圈' }, { text: '微信好友' } ], titleText: '分享到', cancelText: '取消', cancel: function() { hideSheet(); }, buttonClicked: function(index) { //這里的index是ionic彈出框按鈕的索引。 if(index==0){ //微信朋友圈 scene1 = Wechat.Scene.TIMELINE // share to Timeline }else { //微信好友 scene1 = Wechat.Scene.SESSION // share to session } Wechat.share({ message: { //這里的參數名都不要省略 title: "成長特工站", description: "", mediaTagName: "", messageExt: "", messageAction: "", media: { //這里媒體類型不同,對象參數名也不同 type: Wechat.Type.IMAGE, image: photoPath } }, scene: scene1 }, function () { toaster.pop('warning', null, '分享成功!', null, 'trustedHtml'); }, function (reason) { toaster.pop('warning', null, '分享失敗!', null, 'trustedHtml'); }); } }); $timeout(function() { hideSheet(); }, 5000); }
注意:
Wechat.Scene.TIMELINE和Wechat.Scene.SESSION這里的類型需要大寫。
message的參數一個都不能少,不能會有未知錯誤或者json.error。
midea的類型不同,其參數名也不同,具體可見wechat.js(安裝的插件)。
打包的時候,安卓和ios還需要安裝一個插件:
cordova plugin add https://github.com/xu-li/cordova-plugin-wecha
10:input上傳文件與toster.pop配合使用時,toster.pop只出現一次的問題;
如果input file的文件條件不符合,我們需要清空其值,可以用$('xx').val('')。必須使用settimeout異步清空。
11:$ionicActionSheet 在Android手機上樣式問題
在樣式中重寫:
.platform-android .action-sheet-backdrop { -webkit-transition: background-color 150ms ease-in-out; transition: background-color 150ms ease-in-out; position: fixed; top: 0; left: 0; z-index: 11; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0); } .platform-android .action-sheet-backdrop.active { background-color: rgba(0, 0, 0, 0.4); } .platform-android .action-sheet-wrapper { -webkit-transform: translate3d(0, 100%, 0); transform: translate3d(0, 100%, 0); -webkit-transition: all cubic-bezier(0.36, 0.66, 0.04, 1) 500ms; transition: all cubic-bezier(0.36, 0.66, 0.04, 1) 500ms; position: absolute; bottom: 0; left: 0; right: 0; width: 100%; max-width: 500px; margin: auto; } .platform-android .action-sheet-up { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); } .platform-android .action-sheet { margin-left: 8px; margin-right: 8px; width: auto; z-index: 11; overflow: hidden; } .platform-android .action-sheet .button { display: block; padding: 1px; width: 100%; border-radius: 0; border-color: #d1d3d6; background-color: transparent; color: #007aff; font-size: 21px; } .platform-android .action-sheet .button:hover { color: #007aff; } .platform-android .action-sheet .button.destructive { color: #ff3b30; } .platform-android .action-sheet .button.destructive:hover { color: #ff3b30; } .platform-android .action-sheet .button.active, .platform-android .action-sheet .button.activated { box-shadow: none; border-color: #d1d3d6; color: #007aff; background: #e4e5e7; } .platform-android .action-sheet-has-icons .icon { position: absolute; left: 16px; } .platform-android .action-sheet-title { padding: 16px; color: #8f8f8f; text-align: center; font-size: 13px; } .platform-android .action-sheet-group { margin-bottom: 8px; border-radius: 4px; background-color: #fff; overflow: hidden; } .platform-android .action-sheet-group .button { border-width: 1px 0px 0px 0px; } .platform-android .action-sheet-group .button:first-child:last-child { border-width: 0; } .platform-android .action-sheet-options { background: #f1f2f3; } .platform-android .action-sheet-cancel .button { font-weight: 500; } .platform-android .action-sheet-open { pointer-events: none; } .platform-android .action-sheet-open.modal-open .modal { pointer-events: none; } .platform-android .action-sheet-open .action-sheet-backdrop { pointer-events: auto; } .platform-android .action-sheet .action-sheet-title, .platform-android .action-sheet .button { text-align: center; } .platform-android .action-sheet-cancel { display: block; }
12:模仿微信選擇多張圖片(選擇后使用canvas進行壓縮)
ImagePicker.getPictures(function(result) { for (var i = 0; i < result.length; i++) { var target = 420; var reader = new FileReader(); reader.readAsDataURL(file); let src = result[i]; reader.onload = function (event) { // 創建img var image = new Image(); image.setAttribute('crossOrigin', 'anonymous'); image.src = src; image.onload = function () { // 繪制canvas var img = this; var width = img.width; var height = img.height; var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); var ratio = -1; canvas.width = width canvas.height = height ctx.fillStyle = "#fff" ctx.fillRect(0, 0, width, height); ctx.drawImage(img, 0, 0, width, height); if (width >= height){ ratio = target/height; console.log(11111); console.log(ratio); }else { ratio = target/width; console.log(11111); console.log(ratio); } if (ratio > 0){ // 利用canvas的api壓縮圖片 var base64 = canvas.toDataURL('image/jpeg', ratio); // 將壓縮好的數據轉換為blob var blob = base2Blob(base64); console.log(blob.size); // 創建formData var formData = new FormData(); formData.append("file",blob); $http({ method : 'POST', url : API_URL+"school/uploadImage", data : formData, headers: { 'Content-Type': undefined }, transformRequest: angular.identity }).success(function(json){ //$scope.isLoading = false; console.log(JSON.stringify(json)); if(json.code == 1){ $scope.photos.push({ "url":json.data.realPath, "fileType":2 }); console.log($scope.photos) }else{ toaster.pop('warning', null, json.data.desc, 1000, 'trustedHtml'); } }).error(function(XMLHttpRequest, textStatus){ //alert("XMLHttpRequest.status"+XMLHttpRequest.status); //alert("XMLHttpRequest.readyState"+XMLHttpRequest.readyState); //alert("textStatus"+textStatus); toaster.pop('warning', null, '網絡連接異常,請稍后再試!', 1000, 'trustedHtml'); }); }else { var formData = new FormData(); formData.append("file",file); $http({ method : 'POST', url : API_URL+"school/uploadImage", data : formData, headers: { 'Content-Type': undefined }, transformRequest: angular.identity }).success(function(json){ //$scope.isLoading = false; console.log(JSON.stringify(json)); if(json.code == 1){ $scope.photos.push({ "url":json.data.realPath, "fileType":2 }); }else{ toaster.pop('warning', null, json.data.desc, 1000, 'trustedHtml'); } }).error(function(XMLHttpRequest, textStatus){ //alert("XMLHttpRequest.status"+XMLHttpRequest.status); //alert("XMLHttpRequest.readyState"+XMLHttpRequest.readyState); //alert("textStatus"+textStatus); toaster.pop('warning', null, '網絡連接異常,請稍后再試!', 1000, 'trustedHtml'); }); } } } } }, function(err) { alert(err); }, { maximumImagesCount : 9, width : 1920, height : 1440, quality : 100 });
12:video標簽有預加載的屬性(此屬性在打包成ios后的應用里,似乎會有問題)
preload = "auto"
13:ionic中,如果頁面中的元素需要固定在頁面的某個區域,並且此元素的dom位於具有translate3d屬性的元素內,此元素可被拖拽(ios):
方法:在此頁面的路由中,給具有添加translate3d屬性的元素transform:none。不要用js動態添加,可能會造成其他問題。