2015-10-20 3 views
0

Я все еще относительно новичок в Angular, и я пытался создать небольшое приложение, которое может ответить на несколько вопросов и выбрать некоторые фотографии и отправить их на сервер.

У меня возникли некоторые проблемы, позволяющие правильному обновлению области, когда пользователь выбирает изображение. Или, по крайней мере, это то, что мне кажется.

Я считаю, что проблема заключается в контроллере CreateCtrl и, возможно, «ImageService» и/или «FileService».

Вот ссылка на скачивание ионного проекта ... http://newepicweb.com/beaches/beaches_reporter_public.zip

// app.js

angular.module('starter', ['ionic', 'starter.controllers', 'starter.services', 'ngIOS9UIWebViewPatch']) 

    .run(function ($ionicPlatform, $rootScope, $http, $ionicModal) { 

     $ionicPlatform.ready(function() { 

      // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard 
      // for form inputs) 
      if (window.cordova && window.cordova.plugins.Keyboard) { 
       cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); 
       cordova.plugins.Keyboard.disableScroll(true); 

      } 
      if (window.StatusBar) { 
       // org.apache.cordova.statusbar required 
       StatusBar.styleDefault(); 
      } 

      $rootScope.loginToken = window.localStorage['token'] ? window.localStorage['token'] : ''; 
      $rootScope.isLoggedIn = false; 

      if($rootScope.loginToken){ 
       $rootScope.isLoggedIn = true; 
      } 

      // Form data for the login modal 
      $rootScope.loginData = { 
       email: '[email protected]', 
       password: 'xxxxxxxxx' 
      }; 

      // Create the login modal that we will use later 
      $ionicModal.fromTemplateUrl('templates/login.html', { 
       scope: $rootScope 
      }).then(function (modal) { 

       $rootScope.loginModal = modal; 

       if(!$rootScope.isLoggedIn){ 
        $rootScope.login(); 
       } 

      }); 

      // Triggered in the login modal to close it 
      $rootScope.closeLogin = function() { 
       $rootScope.loginModal.hide(); 
      }; 

      // Open the login modal 
      $rootScope.login = function(){ 
       $rootScope.loginModal.show(); 
      } 

      var successfulLogin = function (response){ 
       $rootScope.isLoggedIn = true; 
       $rootScope.loginToken = response.data.token; 
       window.localStorage['token'] = response.data.token; 
       $rootScope.closeLogin(); 
      } 

      var failedLogin = function(response){ 
       alert('Bad credentials. Please try again.'); 
      } 

      // Perform the login action when the user submits the login form 
      $rootScope.doLogin = function() { 
       $http.post('www.site.com', $rootScope.loginData).then(successfulLogin,failedLogin); 
      }; 

     }); 
    }) 

    .config(function ($stateProvider, $urlRouterProvider, $ionicConfigProvider, $compileProvider) { 

     $ionicConfigProvider.backButton.text('').icon('ion-chevron-left').previousTitleText(false); 

     $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel):/); 

     $stateProvider 

      .state('app', { 
       url: '/app', 
       abstract: true, 
       templateUrl: 'templates/menu.html', 
       controller: 'AppCtrl' 
      }) 

      .state('app.welcome', { 
       url: '/welcome', 
       views: { 
        'menuContent': { 
         templateUrl: 'templates/welcome.html' 
        } 
       } 
      }) 

      .state('app.reports', { 
       url: '/reports', 
       views: { 
        'menuContent': { 
         templateUrl: 'templates/reports.html' 
        } 
       } 
      }) 

      .state('create', { 
       url: '/create', 
       abstract: true, 
       templateUrl: 'templates/create.html', 
       controller: 'CreateCtrl' 
      }) 

      .state('create.setup', { 
       url: '/setup', 
       views: { 
        'createContent': { 
         templateUrl: 'templates/create/setup.html' 
        } 
       } 
      }) 

      .state('create.step1', { 
       url: '/step1', 
       views: { 
        'createContent': { 
         templateUrl: 'templates/create/flag.html' 
        } 
       } 
      }) 

      .state('create.step2', { 
       url: '/step2', 
       views: { 
        'createContent': { 
         templateUrl: 'templates/create/water-color.html' 
        } 
       } 
      }) 

      .state('create.confirm', { 
       url: '/confirm', 
       views: { 
        'createContent': { 
         templateUrl: 'templates/create/confirm.html' 
        } 
       } 
      }) 

      .state('create.photos', { 
       url: '/photos', 
       views: { 
        'createContent': { 
         templateUrl: 'templates/create/photos.html' 
        } 
       }, 
       controller: 'CreatePhotosCtrl' 
      }); 


     // if none of the above states are matched, use this as the fallback 
     $urlRouterProvider.otherwise('/app/welcome'); 

}); 

// services.js

angular.module('starter.services', ['ngCordova']) 

.factory('FileService', function($cordovaFile, $q){ 

    function makeId() { 
     var text = ''; 
     var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; 

     for (var i = 0; i < 5; i++) { 
      text += possible.charAt(Math.floor(Math.random() * possible.length)); 
     } 
     return text; 
    }; 

    function saveFile(fileName){ 

     console.log('in fileservice save file'); 

     var defer = $q.defer(); 

     var name = fileName.substr(fileName.lastIndexOf('/') + 1); 
     var namePath = fileName.substr(0, fileName.lastIndexOf('/') + 1); 
     var newName = makeId() + name; 
     try { 
      $cordovaFile.copyFile(namePath, name, cordova.file.dataDirectory, newName).then(function() { 
       console.log('in fileservice file copy file then'); 
       defer.resolve(newName); 
      }); 
     } catch (e){ 
      console.log('fail save file'); 
      defer.reject(); 
     } 

     return defer.promise; 

    }; 

    return { 
     saveFile: saveFile 
    }; 

}) 

.factory('ImageService', function($cordovaCamera, $q) { 

    var images = []; 

    function optionsForType(type) { 
     var source; 
     switch (type) { 
      case 0: 
       source = Camera.PictureSourceType.CAMERA; 
       break; 
      case 1: 
       source = Camera.PictureSourceType.PHOTOLIBRARY; 
       break; 
     } 
     return { 
      destinationType: Camera.DestinationType.FILE_URI, 
      sourceType: source, 
      allowEdit: false, 
      encodingType: Camera.EncodingType.JPEG, 
      popoverOptions: CameraPopoverOptions, 
      saveToPhotoAlbum: false 
     }; 
    }; 

    function getImages(){ 
     return images; 
    } 

    function saveImage(imageName){ 

     console.log('in image save image'); 
     console.log(imageName); 
     images.unshift(imageName); 
    } 

    function addImage(type) { 

     var defer = $q.defer(); 

     var options = optionsForType(type); 

     try { 

      $cordovaCamera.getPicture(options).then(function(imageUri) { 
       console.log('in get picture then'); 
       defer.resolve(imageUri); 
      }); 

     } catch (e) { 
      defer.reject(); 
     } 

     return defer.promise; 

    }; 

    return { 
     addImage: addImage, 
     saveImage: saveImage, 
     getImages: getImages 
    }; 

}); 

// контроллеры .js

angular.module('starter.controllers', ['ngCordova']) 

.controller('AppCtrl', function ($scope, $rootScope) { 

    // With the new view caching in Ionic, Controllers are only called 
    // when they are recreated or on app start, instead of every page change. 
    // To listen for when this page is active (for example, to refresh data), 
    // listen for the $ionicView.enter event: 

    //$scope.$on('$ionicView.enter', function (e) { 
    //}); 

}) 

.controller('CreateCtrl', function ($scope, $ionicPlatform, $ionicHistory, $location, $state, $cordovaDevice, $ionicActionSheet, ImageService, FileService) { 

    var date = new Date; 
    var currentHour = date.getHours(); 
    var year = date.getFullYear(); 
    var month = date.getMonth(); // beware: January = 0; February = 1, etc. 
    var day = date.getDate(); 

    if (currentHour < 10) { 
     var postDate = month + '/' + day + '/' + year + ' 10:00 AM'; 
    } else { 
     if (currentHour > 16) { 
      var postDate = month + '/' + (1 + day) + '/' + year + ' 10:00 AM'; 
     } else { 
      var postDate = month + '/' + day + '/' + year + ' 4:00 AM'; 
     } 
    }; 

    $scope.images = ImageService.getImages(); 

    $scope.backwards = function() { 
     $ionicHistory.goBack(); 
    }; 

    $scope.nextPage = function (path) { 
     $state.go(path); 
    }; 

    $scope.skipPage = function (path, field) { 
     $scope.reportBuilding[field] = null; 
     console.log($scope.reportBuilding); 
     $state.go(path); 
    }; 

    $scope.reportBuilding = { 
     id: null, 
     postDate: postDate, 
     beach: { 
      id: 1, 
      name: 'Clearwater Beach', 
      city: {id: 2, name: 'Clearwater'}, 
      county: {id: 1, name: 'Pinellas County'} 
     }, 
     flag: null, 
     waterSurfaceTemp: null, 
     waterColor: null, 
     respiratoryIrritation: null, 
     deadFish: null, 
     jellyfish: null, 
     debris: null, 
     windDirection: null, 
     surf: null, 
     surfType: null, 
     surfHeight: null 
    }; 

    $scope.addImage = function(type){ 
     $scope.hideSheet(); 
     ImageService.addImage(type).then(function (imageName) { 
      console.log('in image service then'); 
      FileService.saveFile(imageName).then(function(newImage){ 
       console.log('in file save image then', newImage); 
       ImageService.saveImage(newImage); 
       var imgJsonStr = angular.toJson($scope.images, true); 
       console.log('Save Image 1', imgJsonStr) 
       $scope.$apply(); 
       console.log('Images length', $scope.images.length); 
       console.log('Save Image 2', imgJsonStr) 
      }); 
     }); 
    }; 

    $scope.addMedia = function() { 
     console.log('images : ' + $scope.images.length) 
     $scope.hideSheet = $ionicActionSheet.show({ 
      buttons: [{text: 'Take photo'}, {text: 'Photo from library'}], 
      titleText: 'Add Image', 
      cancelText: 'Cancel', 
      buttonClicked: function (index) { 
       $scope.addImage(index); 
      } 
     }); 
    }; 

    $scope.urlForImage = function(imageName){ 
     return cordova.file.dataDirectory + imageName; 
    } 

}); 

// index.html

<!DOCTYPE html> 
<html> 
    <head> 
    <meta charset="utf-8"> 
    <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"> 
    <title></title> 

    <link href="lib/ionic/css/ionic.css" rel="stylesheet"> 
    <link href="lib/Ionicons/css/ionicons.min.css" rel="stylesheet"> 
    <link href="css/style.css" rel="stylesheet"> 

    <!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above 
    <link href="css/ionic.app.css" rel="stylesheet"> 
    --> 

    <script type="text/javascript"> 
     window.onerror = function(message, url, lineNumber) { 
      console.log("Error: "+message+" in "+url+" at line "+lineNumber); 
     } 
    </script> 

    <!-- ionic/angularjs js --> 
    <script src="lib/ionic/js/ionic.bundle.js"></script> 

    <!-- cordova script (this will be a 404 during development) --> 
    <script src="lib/ngCordova/dist/ng-cordova.js"></script> 
    <script src="cordova.js"></script> 

    <!-- your app's js --> 
     <script src="js/app.js"></script> 
     <script src="js/controllers.js"></script> 
     <script src="js/services.js"></script> 
     <script src="js/ngIOS9UIWebViewPatch.js"></script> 

    </head> 

    <body ng-app="starter"> 
    <ion-nav-view></ion-nav-view> 
    </body> 
</html> 

// create.html

<ion-header-bar class="bar bar-header"> 
    <h1 class="title">BEACH CONDITION REPORTING SYSTEM</h1> 
</ion-header-bar> 
<ion-header-bar class="bar bar-subheader"> 
    <img src="img/mote-logo.png" class="logo center-block" /> 
</ion-header-bar> 
<ion-nav-view name="createContent"></ion-nav-view> 

// Шаблоны/photos.html

<ion-view> 
    <ion-content class="hidden-backbutton"> 
     <div class="transparent-overlay"> 
      <button class="button button-full button-energized" ng-click="addMedia()"> 
       Add image 
      </button> 
      <br><br> 
      <ion-scroll direction="y"> 
       <div class="card" ng-repeat="image in images track by $index" > 
        <div class="item image"> 
         <img ng-src="{{urlForImage(image)}}" class="full-image" /> 
        </div> 
        <div class="item item-divider"> 
         <button class="button button-assertive button-block button-clear icon icon-right ion-close">Remove Photo</button> 
        </div> 
       </div> 
      </ion-scroll> 
     </div> 
    </ion-content> 
    <ion-footer-bar align-title="left" class="bar-stable"> 
     <div class="buttons"> 
      <button class="button button-clear icon ion-chevron-left icon-left" ng-click="backwards()"> &nbsp;&nbsp;&nbsp; Back</button> 
     </div> 
     <div class="title">1 of 8</div> 
     <div class="buttons"> 
     </div> 
    </ion-footer-bar> 
</ion-view> 

XCode Console Log Output

2015-10-20 14:56:14.399 beaches_reporter[4704:1733175] Apache Cordova native platform version 3.8.0 is starting. 
2015-10-20 14:56:14.400 beaches_reporter[4704:1733175] Multi-tasking -> Device: YES, App: YES 
2015-10-20 14:56:14.411 beaches_reporter[4704:1733175] Unlimited access to network resources 
2015-10-20 14:56:14.623 beaches_reporter[4704:1733175] [CDVTimer][keyboard] 0.474036ms 
2015-10-20 14:56:15.335 beaches_reporter[4704:1733175] [CDVTimer][splashscreen] 711.232007ms 
2015-10-20 14:56:15.418 beaches_reporter[4704:1733175] [CDVTimer][file] 83.101034ms 
2015-10-20 14:56:15.419 beaches_reporter[4704:1733175] [CDVTimer][TotalPluginStartup] 796.294987ms 
2015-10-20 14:56:15.771 beaches_reporter[4704:1733175] Resetting plugins due to page load. 
2015-10-20 14:56:16.239 beaches_reporter[4704:1733175] Finished load of: file:///var/mobile/Containers/Bundle/Application/848C1D5C-5F75-4BD1-821D-6203CF17E2FA/beaches_reporter.app/www/index.html#/app/welcome 
    2015-10-20 14:56:23.694 beaches_reporter[4704:1733175] images : 0 
2015-10-20 14:56:29.187 beaches_reporter[4704:1733175] in get picture then 
2015-10-20 14:56:29.187 beaches_reporter[4704:1733175] in image service then 
2015-10-20 14:56:29.188 beaches_reporter[4704:1733175] in fileservice save file 
2015-10-20 14:56:29.343 beaches_reporter[4704:1733175] THREAD WARNING: ['File'] took '144.152100' ms. Plugin should use a background thread. 
2015-10-20 14:56:29.373 beaches_reporter[4704:1733175] in fileservice file copy file then 
2015-10-20 14:56:29.373 beaches_reporter[4704:1733175] in file save image then uxwHQcdv_photo_011.jpg 
2015-10-20 14:56:29.374 beaches_reporter[4704:1733175] in image save image 
2015-10-20 14:56:29.374 beaches_reporter[4704:1733175] uxwHQcdv_photo_011.jpg 
2015-10-20 14:56:29.374 beaches_reporter[4704:1733175] Save Image 1 [ 
    "uxwHQcdv_photo_011.jpg" 
    ] 
2015-10-20 14:56:29.374 beaches_reporter[4704:1733175] Images length 1 
2015-10-20 14:56:29.374 beaches_reporter[4704:1733175] Save Image 2 [ 
    "uxwHQcdv_photo_011.jpg" 
    ] 
+0

любая ошибка консоли? – FRECIA

+0

Кажется, не было никаких ошибок. Я обновил контроллер и службы js немного, чтобы вывести в журнал несколько разных мест, а также отобразить обновленную переменную $ scope.images. Они отображаются для меня в Xcode, поэтому я могу сказать, что это делается для решения FileService.saveFile (imageName) .then(). –

+0

Просто добавил консольный выход. –

ответ

1

Очень много кода, чтобы пройти, но что, если вы вынуждаете $ scope.apply обновлять свой массив изображений?

 $scope.addImage = function(type){ 
      $scope.hideSheet(); 
      ImageService.addImage(type).then(function (imageName) { 
       console.log('in image service then'); 
       FileService.saveFile(imageName).then(function(newImage){ 
        console.log('in file save image then', newImage); 
        ImageService.saveImage(newImage); 
        var imgJsonStr = angular.toJson($scope.images, true); 
        console.log('Save Image 1', imgJsonStr) 

       $scope.$apply(function() { 
        $scope.images[] = imgJsonStr; 
       }); 

        console.log('Images length', $scope.images.length); 
        console.log('Save Image 2', imgJsonStr) 
       }); 
      }); 
     }; 
+0

Я попробовал $ scope. $ Apply (function() {$ scope.images [] = ImageService.getImages();}); 'и что, кажется, происходит, когда я выбираю изображение, все проходит, но видимый просмотр не обновляется. Но затем я нажимаю назад и возвращаюсь к просмотру с фотографиями, он обновляется. –