我尝试使用Ionic / Angular / Cordova构建移动应用程序,我在使用服务时遇到一些问题:)我的代码如下所示:
SERVICE:
'use strict';
angular.module('MyDemoApp.services').service('ImageService', function($cordovaCamera, $cordovaFile) {
// 1
//$scope.images = [];
this.addImage = function (method){
var imageDetails ={'name':'',
'src':''
};
// 2
// Set the "options array" [who is passed to the cordovaCamera] by method [take | choose]
// Docs : http://plugins.cordova.io/#/package/org.apache.cordova.camera
var options ={};
if (method==='take'){
options = {
destinationType : Camera.DestinationType.FILE_URI,
sourceType : Camera.PictureSourceType.CAMERA,
allowEdit : false,
encodingType: Camera.EncodingType.JPEG,
popoverOptions: CameraPopoverOptions,
};
} else if (method==='choose'){
options = {
destinationType : Camera.DestinationType.FILE_URI,
sourceType : Camera.PictureSourceType.PHOTOLIBRARY,
allowEdit : false,
encodingType: Camera.EncodingType.JPEG,
popoverOptions: CameraPopoverOptions,
};
}
// 3
// Call the ngCodrova module cordovaCamera we injected to our service.
$cordovaCamera.getPicture(options).then(function(imageData) {
// 4
// When the image capture returns data, we pass the information to our success function,
// which will call some other functions to copy the original image to our app folder.
onImageSuccess(imageData);
function onImageSuccess(fileURI) {
createFileEntry(fileURI);
}
function createFileEntry(fileURI) {
window.resolveLocalFileSystemURL(fileURI, copyFile, fail);
}
// 5
// This function copies the original file to our app directory.
// We have to deal with duplicate images, we give a new name to the file consisting of a random string and the original name of the image.
function copyFile(fileEntry) {
var name = fileEntry.fullPath.substr(fileEntry.fullPath.lastIndexOf('/') + 1);
var newName = makeid() + name;
window.resolveLocalFileSystemURL(cordova.file.dataDirectory, function(fileSystem2) {
fileEntry.copyTo(
fileSystem2,
newName,
onCopySuccess,
fail
);
},
fail);
}
// 6
// If the copy task finishes successful, we push the image url to our scope array of images.
// Make sure to use the apply() function to update the scope and view!
function onCopySuccess(entry) {
window.alert('success');
imageDetails.name=entry.name;
imageDetails.src=entry.nativeURL;
// Here I get the corect data that I want to send to the controller
window.alert('imageDetails='+ JSON.stringify(imageDetails));
}
function fail(error) {
window.alert("Fail: " + error.code);
}
function makeid() {
var text = '';
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (var i=0; i < 5; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
}, function(err) {
window.alert(err);
});
return imageDetails;
}; // end addImage();
});
CONTROLLER:
'use strict';
angular.module('MyDemoApp.controllers')
.controller('SignupCtrl', function ($scope, ImageService) {
$scope.user = {};
$scope.addNewImage = function (method){
/* V1 WHAT I'VE TRIED */
var test = ImageService.addImage(method)
$scope.user.image = test;
window.alert('Final '+JSON.stringify(test));
/* V1 WHAT I'VE TRIED */
/*
ImageService.addImage(method).then(function(data){
window.alert('Final'+JSON.stringify(data));
$scope.user.image = data.src;
},function(err){
window.alert('add image error: === ' + JSON.stringify(err));
});
*/
}
});
我想要的是在$ scope.user.image上设置我在onCopySuccess(来自服务)中得到的值(但仅当服务完成他的工作......才能获得正确的数据)。
但是$ scope.user.image一直都是空的,我将首先看到window.alert('Final'+ JSON.stringify(test));然后只有来自onCopySuccess的警报(window.alert('success');)
我正在使用服务,因为我需要为用户,照片库和其他应用部分添加图片功能
我非常感谢任何帮助。 感谢
答案 0 :(得分:0)
$cordovaCamera.getPicture
返回一个promise,因此它是异步的。您将返回一个您还没有的值。你的addImage
函数应该返回一个promise,你的控制器应该使用该promise的结果。
https://docs.angularjs.org/api/ng/service/ $ Q
基本上:
1)使用deferred
$q.defer()
对象创建新的addImage()
2)在deferred.promise
addImage()
3)在deferred.resolve(imageDetails)
onCopySuccess
4)以下列方式使用它:
ImageService.addImage(method).then(function(data){
window.alert('Final'+JSON.stringify(data));
$scope.user.image = data.src;
});
您还应该处理错误(有关详细信息,请参阅角度文档)。
答案 1 :(得分:0)
您必须从承诺中返回数据并从服务中返回承诺,然后将其与.then()一起使用,就像在注释掉的代码中一样。
服务代码:
this.addImage = function (method){
var imageDetails ={'name':'', 'src':''};
...
return $cordovaCamera.getPicture(options).then(function(imageData) {
...
return imageDetails;
}, function(err) {
window.alert(err);
});
};
控制器代码:
ImageService.addImage(method).then(function (imageDetails){
window.alert('Final'+JSON.stringify(imageDetails));
$scope.user.image = imageDetails.src;
},function (err){
window.alert('add image error: === ' + JSON.stringify(err));
});