ionic + cordova+angularJs 搭建的H5 App完整版總結

   爲期半個月的項目實踐開發,已完整告一段落,團隊小組得到第一名,辛苦總算沒有白費,想起有一天晚上,整個小組的人,聯調到12點才從公司回去,真是心酸。這裏總結一下,項目過程當中遇到的問題javascript

和感悟。哈哈,放張集體照。嘿嘿,項目全部的不一樣的team的小夥伴,一羣優秀的小夥伴(大多都來自高校211,985)麼麼噠.下面介紹下咱們組的產品和問題。html

項目已放在github上:https://github.com/foreverjiangting/myApp/tree/master/myApp/myApp前端

一:項目效果展現java

     先展現一下咱們作的產品,主要是作一個投票的APP,包括用戶登陸,註冊,答卷,查看答卷詳情,排行榜等功能。後臺可建立問卷,分發問卷,增長單選題和多選題,建立問卷題目,我這邊前端的app將其顯git

示出來。基本上能夠知足需求,但還有不少不完善的地方。angularjs

               

二:製做功能問題總結github

     先看下核心功能,用戶進行單選,多選後,將保存用戶的答案,傳遞後後端,而後在展現詳情裏面將用戶的答案進行展現出來。這裏先貼下代碼。ajax

 <ion-slide-box show-pager="false"  on-slide-changed="onSlideChanged(index)" active-slide="currentIndex">
			<ion-slide  class="set-container" ng-repeat="value in  objData"  repeat-done="repeatDone()" >
			    <div class="swiper-slide swiper-slide-duplicate swiper-slide-active"  style="width: 349px; margin-right: 30px;">
					<div class="scores" >
						<h3>{{data.title}}</h3>
						<div class="f"><span id="span-text">{{$index+1}}</span>{{value.title}}</div>
						<div class="choose">
							<div class="input" ng-repeat="(key,value2) in value.items">
							   <label for="26">
							      <input type="radio" name="radio{{$parent.$index}}" class="radio"  value="{{key}}" ng-model= "selectedValue.radioData[$parent.$index]"> 
							      <span >{{value2}}</span> 
							   </label>
							</div>														
						</div>
					</div>
				</div>
</ion-slide>

這裏有幾個問題,因爲是公用同一個模板,每個ion-slide就是一頁,且一頁下面有多個選項。問題以下:json

1.如何區分不一樣個ion-slide下的radio ?貼下代碼,只要給name添加就能夠。$parent.$index便可後端

   <input type="radio" name="radio{{$parent.$index}}" class="radio" 

2.如何獲取用戶選擇的當前頁的答案?使用ng-model便可,將用戶選擇的答案分別存在一個數組裏面。

ng-model= "selectedValue.radioData[$parent.$index]"> 

  基本上也沒啥難點,就是方法要知道。用戶填寫答案完成後,進行保存,咱們須要獲取用戶提交的全部答案。看下代碼。

 $scope.submitData = {};
    //用戶提交完畢,當前的問卷被提交,修改其狀態爲已完成。可在已完成的欄目進行查看
    $scope.submitSuccess = function(){
       
        var radioJsonData = $scope.selectedValue.radioData;
        var radioObject  = [];
        for(var k  in radioJsonData){
             radioObject.push(radioJsonData[k]);
        }
        console.log('3333')
        console.log(radioObject);
        console.log(radioJsonData)
        //獲取radioData的長度,判斷用戶選擇的數據是否完整
        var radioLength = 0;
        var getRadioLength = function(radioJsonData){
            for(var item  in radioJsonData){
                radioLength++;
            }
            return  radioLength;
        }
        if(getRadioLength(radioJsonData) == $scope.serveLength-1){
              var submitData = window._single = {
                  "single":radioObject            
              }; 
              var submitId  = window._id = {
                   "id" : $stateParams.timuId
              } 
               console.log(JSON.stringify(submitData));
               var alertPopup = $ionicPopup.alert({
                   title: '保存成功',
                   template: '您的單選題已完成,請繼續答題!'
               });
               alertPopup.then(function(res) {
                   history.go(-1);
               });
        } else{
            var alertPopup = $ionicPopup.alert({
                title: '提交失敗',
                template: '您的問卷未完成,請返回查看詳情!'
            });
            alertPopup.then(function(res) {
               console.log('提交失敗');
            });
        }      
    };

 3.再來看下多選題,跟單選題有點區別。

 <ion-slide-box show-pager="false"  on-slide-changed="onSlideChanged(index)" active-slide="currentIndex">
			<ion-slide  class="set-container" ng-repeat="value in  objData"  repeat-done="repeatDone()" >
			    <div class="swiper-slide swiper-slide-duplicate swiper-slide-active"  style="width: 349px; margin-right: 30px;">
					<div class="scores">
						<h3>{{data.title}}</h3>
						<div class="f"><span id="span-text">{{$index+1}}</span>{{value.title}}</div>
						<div class="choose" >
							<div class="input" ng-repeat="(key,value2) in value.items">
							   <label for="26">
							      <input type="checkbox" name="radio{{$parent.$index}}" class="radio"  
							      ng-model = "selected[$parent.$index][$index]"
							     > 
							      <span  style="margin-left: 30px;">{{value2}}</span> 
							   </label>
							</div>														
						</div>
					</div>
				</div>
                       </ion-slide>

 問題以下:

1.如何在多選裏面選中多個答案呢?

  ng-model = "selected[$parent.$index][$index]"

這種方法是最簡單的,雖然不是咱們要的,但以後再作一下解析便可。數組裏面的數據是這樣子的。由於咱們只須要保存用戶選擇的答案的當前題目的index,保存以1,2,3,4的形式保存便可。

         

看下解析的代碼以下:

 $scope.nextSlide = function(){ 
        var  slideIndex = $ionicSlideBoxDelegate.currentIndex();       
        $scope.connectedData = $scope.selected.map(function(item){
            var connectSelected = [];
            for(var i in item){
              if(item[i]){
                connectSelected.push(parseInt(i)+1);
              }
            }
            return connectSelected.join('/');     //進行解析,以/進行分割
        })

        if( $scope.connectedData == null){
             var alertPopup = $ionicPopup.alert({
                 template: '您尚未選擇,請選擇答案!'
            }); 
        }else if( $scope.connectedData[slideIndex] == null && slideIndex != $scope.serveLength-1 ){
            var alertPopup = $ionicPopup.alert({
                 template: '您尚未選擇,請選擇答案!'
            });  
            return true;           
        }else {
            $ionicSlideBoxDelegate.next(); 
        }
          return ;    
          console.log('test:'+JSON.stringify( $scope.connectedData));
        //$ionicSlideBoxDelegate.next();                     
    };

3.既然單選題和多選題都有答案了,如今就是提交用戶答案了。解決不一樣controller之間的數據通訊,原本以前用的$rootscope,不知道爲何不行,後來學霸告訴我直接

存在window下面。因而簡單粗暴的解決了問題。

         

 

先看下代碼吧,咱們前端須要提交給後端數據包括問卷的ID,單選題答案,多選題答案。下面是提交的代碼。

.controller('chooseCtrl',['$scope','$ionicPopup', '$timeout', '$stateParams','$http','$ionicScrollDelegate','$location' ,function($scope,$ionicPopup, $timeout, $stateParams,$http,$ionicScrollDelegate,$location){
    $scope.jump = function(url){
          window.location = url;
    }
      $scope.chooseId = $stateParams.timuId; //獲取問卷的Id
      console.log( $scope.chooseId);
      var submitData = {
           "id" : $scope.chooseId
      }
      var objData = [];
      //剛開始渲染數據,獲取整個問卷的data,單選存在一個數組,多選存在一個數組
    $http({  
           // url : "../data/api.json", 
            url : "http://10.32.33.4:8080/ivotel-management/questionnaire/selectQuestionnaireDetail", 
            method : "get",
            params: submitData,
            headers: { 'Content-Type': 'application/json;charset=UTF-8' }
    }).success(function(data) {         
            var arr =data.questionnaireQuestionList; //進行解析          
            var singleData = [] ;
            var mutilData = [];
            for(var i=0;i<arr.length;i++){
                  objData[i] = arr[i].responseQuestion; 
            } 
           // console.log(JSON.stringify(objData));  //獲取全部的題目對象
            for(var i  in  objData){
                   if(objData[i].questiontype == 1){
                        singleData.push(objData[i]);
                   }else if(objData[i].questiontype == 2){
                        mutilData.push(objData[i]);
                   }
            }
            window._singleData = singleData;
            window._singleData_length = singleData.length;
            window._mutilData  = mutilData;
            window._mutilData_length = mutilData.length;
            window.totalQuestionData = data ;
            //console.log(JSON.stringify(singleData));
            //console.log(JSON.stringify(mutilData));     
            $scope.data = data; 
            $scope.serveData = data.questionnaireQuestionList[0].qqid;     
    }).error(function(){  
            console.log('error');
    });
    
    //用戶填寫完成後,將用戶答案保存,並一塊兒傳遞給後端 
    $scope.submit = function(){
          if(window._multi == null){
              window._multi = [];
          }
          var  submitTotalData = [
                window._id ,
                window._single , 
                window._multi
          ] ;
             $http({  
                  url : "http://10.32.33.4:8080/ivotel-examuser/questionnairePapers/Submit",  
                  method : "post",
                  data : submitTotalData,
                  headers: { 'Content-Type': 'application/json;charset=UTF-8' },
                  withCredentials :true
              }).success(function(data) { 
                  console.log('success');
              }).error(function(){  
                  console.log('error');
              });  
               var alertPopup = $ionicPopup.alert({
                   title: '提交成功',
                   template: '您的問卷已完成,請返回查看詳情!'
               });
                alertPopup.then(function(res) {
                   history.go(-1);
              });
              
            console.log('test: ' + JSON.stringify( submitTotalData));         
    }

}])

輸出時用戶提交的全部答案格式以下:

將不一樣的controller裏面的值,分別存在window下面的某一個屬性下面,便可在全局中進行使用。

   

4.OK ,既然答案都已經保存好啦,如今,咱們須要將答案展現出來。在詳情頁面列表中。

  看下後端傳給咱們的數據格式以下:

{
    "answer": {  //單選
        "1": "4",  //第一題,用戶選擇第四個答案
        "2": "1",  //第二題,用戶選擇第一個答案
        "3":"3"    //第三題,用戶選擇第三個答案
    },
    "multi": {    //多選
        "4": "1/2/3",  //第四題,用戶選擇1,2,3答案
        "5": "1/3/4",  //第五題,用戶選擇1,3,4答案
        "6": "1/3/4"   //第六題,用戶選擇1,3,4答案
    }
}

看下效果圖,咱們主要是作兩件事,1.進行解析,將用戶的答案,呈現出來。2.根據答案,選中用戶當前的radio的狀態。

       

這裏直接貼下代碼,解析的過程都在代碼中。比較繁瑣。

關於單選的話,根絕單選直接選中當前的radio,比較好說,直接使用下面的方法便可:

<ion-slide  class="set-container" ng-repeat="value in  singleData"  repeat-done="repeatDone()" >
			    <div class="swiper-slide swiper-slide-duplicate swiper-slide-active"  style="width: 349px; margin-right: 30px;">
					<div class="scores" >
						<h3>{{data.title}}</h3>
						<div class="f"><span id="span-text">{{$index+1}}</span>{{value.title}}</div>
						<div class="choose">
							<div class="input" ng-repeat="(key,value2) in value.items">
							   <label for="26">
							      <input type="radio" name="radio{{$parent.$index}}" class="radio"  value="{{value2}}" 
							       ng-checked="$index == selectedIndex-1"> 
							      <span >{{value2}}</span> 
							   </label>
							</div>														
						</div>
					</div>
				</div>
</ion-slide>

 即直接使用下面的方法:ng-checked = "$index == selectedIndex -1"便可.

  ng-checked="$index == selectedIndex-1"> 

 這裏解析的代碼也貼一下:

.controller('listItemCtrl',['$scope','$ionicPopup', '$timeout', '$stateParams','$http','$ionicScrollDelegate','$location' ,'$ionicSlideBoxDelegate','$ionicHistory',
  function($scope,$ionicPopup, $timeout,$stateParams,$http,$ionicScrollDelegate,$location,$ionicSlideBoxDelegate,$ionicHistory){  
          // $ionicHistory.nextViewOptions({
          //        disableBack: true
          // });
          $scope.repeatDone = function() {
             $ionicSlideBoxDelegate.update();
          };
          var  objData = [];
          $scope.selectedValue = {};
          $scope.radioData = [];
          $scope.wenjuanId = $stateParams.timuId; //獲取問卷的Id
          console.log('問卷Id:' + $scope.wenjuanId);
          var submitData = {
               "id" :  $scope.wenjuanId 
          }
          $scope.serveData = 0;       
          $scope.objData = null;
          $scope.jsonRadio = [];                
          $scope.newJsonData = []; //根據對應的題目索引,獲得正確的題目
          $scope.newMulitJsonData = [];
          $scope.currentIndex = 0;
          $scope.answerData = null;  //全部的單選題的答案
          $scope.answerMutleData = null;
          $scope.jsonItemData = null;
          $scope.selectedIndex = 0;
          $scope.answerArray = [];
          $scope.singleData = []; //全部的單選題 
          $scope.multiData = [];
          $scope.serveLength = 0;
          $scope.selectedMulitIndex = 0;
          $scope.chooseMulitData = [];
          $scope.single_length = 0;
          $scope.muiteKey = 0;
          $scope.arrData = [];
          $http({  
                  url : "../data/doing.json", 
                  //url : "http://10.32.33.4:8080/ivotel-examuser/questionnairePapers/PaperDetail", 
                  method : "get",
                  params: submitData,
                  headers: { 'Content-Type': 'application/json;charset=UTF-8' },
                  withCredentials :true
          }).success(function(data) {                   
                    $scope.answerData = data.answer;  
                    console.log($scope.answerData);  //獲得用戶選擇的答案 {1: "1", 2: "2"}                
                    var arr = data.questionnaireTemp.questionnaireQuestionList; //進行解析                        
                    for(var i=0; i< arr.length;i++){             //獲取全部的題目對象
                        objData[i] = arr[i].responseQuestion; 
                    }
                    $scope.data = data;                              
                    $scope.objData = objData;
                    $scope.serveLength = objData.length;
                    //console.log( $scope.serveLength)
                    //console.log(JSON.stringify( $scope.objData));    

                    for(var i  in  objData){                   //將單選題 和 多選題分別存在不一樣的數組裏面
                           if(objData[i].questiontype == 1){
                                 $scope.singleData.push(objData[i]);
                                 $scope.single_length =  $scope.singleData.length -1 ;
                           }else if(objData[i].questiontype == 2){
                                 $scope.multiData.push(objData[i]);
                           }
                    } 
                    //若是爲單選的話,爲 $scope.singleData                                                         
                    for(var i  in  $scope.answerData){   //i爲key值開始
                        if(i == ($ionicSlideBoxDelegate.currentIndex()+1)){
                            $scope.newJsonData.push($scope.singleData[i-1].items[($scope.answerData[i])]);
                        }                                          
                    }
                    $scope.selectedIndex = parseInt($scope.answerData[$ionicSlideBoxDelegate.currentIndex()+1]) ; 
                    console.log('selectedIndex : ' +$scope.selectedIndex)                 
                    console.log('jsonNewData:' + JSON.stringify( $scope.newJsonData));  

                    //若是爲多選的話,爲$scope.multiData
                    $scope.answerMutleData = data.multi;
                    console.log( JSON.stringify($scope.answerMutleData));

                    //對數組進行解析
                    var temp = 0;
                    for(var i  in $scope.answerMutleData){ //i爲3 
                        var arr = $scope.answerMutleData[i].split('/');
                        $scope.arrData = arr ;
                        for (var i  in arr){
                            // $scope.muiteKey = arr[i]; //獲取key值,並賦值給全局變量
                        }
                       // $scope.muiteKey = arr[$ionicSlideBoxDelegate.currentIndex()]
                        console.log('arr : ' + JSON.stringify(arr));  //[1,2,3]
                        console.log('key: ' +  JSON.stringify($scope.arrData));
                        for(var j=0;j < arr.length; j++){
                             console.log('test: ' +temp );
                             if(i == ($ionicSlideBoxDelegate.currentIndex()+1)){
                                  $scope.newMulitJsonData.push($scope.multiData[temp].items[(arr[j])]);
                             }    
                        }
                        temp++;
                        console.log('arrDate:' + JSON.stringify($scope.arrData));  
                    }  
                        console.log($scope.newMulitJsonData);

                    //全部的單選所有展現完成後,開始展現全部的多選
                    $scope.selectedMulitIndex = parseInt($scope.answerMutleData[$ionicSlideBoxDelegate.currentIndex()+1]) ; 
                    $scope.muiteKey = parseInt($scope.answerMutleData[$ionicSlideBoxDelegate.currentIndex()+1]) ; 
                    console.log( $scope.selectedMulitIndex);

            }).error(function(){  
                  console.log('error');
          });        
          $scope.jsonItemData = [];
          var osingMes = document.getElementById('singleMessage');
          var omulit   = document.getElementById('muiltMessage');  
          $scope.onSlideChanged = function(index){
              $scope.currentIndex = index;
              for(var i  in $scope.answerData){
                    $scope.answerArray.push($scope.answerData[i]);
              }
              console.log('index22:' + index);
              $scope.selectedIndex = parseInt($scope.answerData[$ionicSlideBoxDelegate.currentIndex()+1])-1 ; 

              console.log('selectedIndex : ' +$scope.selectedIndex)                              
              for(var i  in  $scope.answerData){
                        if(i == ($ionicSlideBoxDelegate.currentIndex()+1)){
                            $scope.newJsonData.push($scope.singleData[i-1].items[($scope.answerData[i])]);
                            $scope.selectedIndex = $scope.answerData[i] - '0' ;
                        }
                        console.log('index:' + $scope.selectedIndex)
                      
              }
              // if($ionicSlideBoxDelegate.currentIndex()+1 >  $scope.serveLength){
              //       osingMes.style.display = 'none';
              //       omulit.style.display = 'block';
              // }
              console.log('jsonNewData:' + JSON.stringify( $scope.newJsonData)); 
              //若是爲多選的話,爲$scope.multiData
                  //  $scope.answerMutleData = data.multi;
                    console.log( JSON.stringify($scope.answerMutleData));
                    //對數組進行解析
                    var temp = 0;
                    for(var i  in $scope.answerMutleData){ //i爲3 
                       // var b =  $scope.newMulitJsonData;  //將上一次的值賦給b
                        console.log('length :' + $scope.newMulitJsonData.length);                    
                              var arr = $scope.answerMutleData[i].split('/');
                              for(var j=0;j < arr.length; j++){
                                   console.log('test: ' + temp );
                                   if(i == ($ionicSlideBoxDelegate.currentIndex()+1)){
                                        if($scope.newMulitJsonData[j] == null){   //判斷以前的全部選項是否爲空 
                                           $scope.newMulitJsonData.push($scope.multiData[temp].items[(arr[j])]);
                                           $scope.muiteKey = $scope.multiData[temp] - '0';

                                        }else{
                                           $scope.newMulitJsonData = [];
                                           $scope.newMulitJsonData.push($scope.multiData[temp].items[(arr[j])]);
                                        }
                                   } 
                                     console.log('json: '+ JSON.stringify($scope.newMulitJsonData));    
                              }
                              temp++;                                                                    
                             //[1,2,3]                                             
                    }                   
                    console.log(JSON.stringify($scope.newMulitJsonData));  
                    for(var i  in $scope.newMulitJsonData){
                        console.log('i:'+ i);
                    }
                                
                    //console.log($scope.newMulitJsonData); //獲得的正確答案沒問題
                    //全部的單選所有展現完成後,開始展現全部的多選
                    $scope.selectedMulitIndex = parseInt($scope.answerMutleData[$ionicSlideBoxDelegate.currentIndex()+1]) ; 
                    console.log( $scope.selectedMulitIndex);
              
          };
           $scope.nextSlide = function(){ 
              if($ionicSlideBoxDelegate.currentIndex()+1 !=  $scope.serveLength) {
                      $ionicSlideBoxDelegate.next();  
              }else {
                      var alertPopup = $ionicPopup.alert({                 
                           template: '親,已經最後一題,木有了哦!'
                      });
                      alertPopup.then(function(res) {
                           // window.location.reload();
                           // history.go(-1);
                      });
              }
                
          };

          $scope.startSlide = function(){
              $ionicSlideBoxDelegate.previous();
          };
}])

5.先後端跨域的問題。

  因爲angularjs的$http請求與ajax仍是有些區別的,老是會存在跨域的問題,如何解決呢?加個 withCredentials :true 便可。

 $http({  
                  url : "http://10.32.33.4:8080/ivotel-examuser/questionnairePapers/Submit",  
                  method : "post",
                  data : submitTotalData,
                  headers: { 'Content-Type': 'application/json;charset=UTF-8' },
                  withCredentials :true
              }).success(function(data) { 
                  console.log('success');
              }).error(function(){  
                  console.log('error');
              }); 
})  

OK,基本上整個核心的功能點都已經講解清楚啦。問題仍是遇到很多,感謝從不拒絕我問題的shu,給了我很大的幫助。嘿嘿,麼麼噠!

 三:總結

     通過這個月的項目實踐,熟悉了很多ng的寫法,雖然之前也接觸過,但好像都不是很熟,並且一個完整的APP的搭建流程也熟悉不少。其次,想說到先後端合做的問題,定契約的問題,溝通問題

感受一個項目下來,反正各類問題都碰到,你們一塊兒吵啊,爭啊,各有各的想法,拍桌子啊,先後端互相抱怨啊,雖然意見各有不一樣,哈哈哈,仍是很高興的!起碼團隊頗有活力,頗有想法,要都是

不吭聲,那才恐怖,本身搞本身的,誰知道你什麼想法。哈哈哈,喜歡咱們的團隊,一個個都棒棒的!另外呢,作項目的時候呢,要知道每一個人都有本身的想法,因此,不要一昧的否定別人的想法,覺

得本身就是對的(傻逼), 學會傾聽,很關鍵。團隊得到了第一名,你們都很開心,當晚咱們組你們一塊兒去吃了海鮮自助。哈哈,放張照片!

       

     仍是喜歡和本身年齡相仿的人一塊兒工做,作項目,開開玩笑,多開心。天天充滿了激情和活力,溝通無代溝,都是90後,一羣年輕人,多好!但是,事與願違啊!接下來,仍是得適應不一樣年齡段的人!


 

做者:婷風

 出處:http://www.cnblogs.com/jtjds/p/6128539.html 

 若是您以爲閱讀本文對您有幫助,請點一下「推薦」按鈕,您的「推薦」將是我最大的寫做動力!歡迎各位轉載,可是未經做者本人贊成 

轉載文章以後必須在 文章頁面明顯位置給出做者和原文鏈接不然保留追究法律責任的權利。

相關文章
相關標籤/搜索