總結angular+ionic項目中的問題


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:打包成原生應用后如何實現存儲圖片到相冊和分享至微信的功能。

github例子地址

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進行壓縮)

github地址

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動態添加,可能會造成其他問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM