Angularjs 无法从控制器中的服务获取正确的数据
Angularjs Cannot get the correct data from a service in a controller
我尝试使用 Ionic/Angular/Cordova 构建一个移动应用程序,但我遇到了一些服务问题 :) 我的代码如下所示:
服务:
'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();
});
控制器:
'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');)
我正在使用一项服务,因为我需要为用户、照片库和其他应用部分添加图片功能
非常感谢任何帮助。
谢谢
$cordovaCamera.getPicture
return是一个承诺,因此它是异步的。您正在 return 获得一个您还没有的价值。您的 addImage
函数应该 return 一个承诺,您的控制器应该使用该承诺的结果。
https://docs.angularjs.org/api/ng/service/$q
基本上:
1) 使用 addImage()
中的 $q.defer()
对象创建一个新的 deferred
2) return deferred.promise
addImage()
结尾
3) 在 onCopySuccess
中调用 deferred.resolve(imageDetails)
4) 按以下方式使用:
ImageService.addImage(method).then(function(data){
window.alert('Final'+JSON.stringify(data));
$scope.user.image = data.src;
});
您还应该处理错误(有关详细信息,请参阅 angular 文档)。
您必须 return 来自 promise 的数据和 return 来自服务的 promise,然后将其与 .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));
});
我尝试使用 Ionic/Angular/Cordova 构建一个移动应用程序,但我遇到了一些服务问题 :) 我的代码如下所示:
服务:
'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();
});
控制器:
'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');)
我正在使用一项服务,因为我需要为用户、照片库和其他应用部分添加图片功能
非常感谢任何帮助。 谢谢
$cordovaCamera.getPicture
return是一个承诺,因此它是异步的。您正在 return 获得一个您还没有的价值。您的 addImage
函数应该 return 一个承诺,您的控制器应该使用该承诺的结果。
https://docs.angularjs.org/api/ng/service/$q
基本上:
1) 使用 addImage()
$q.defer()
对象创建一个新的 deferred
2) return deferred.promise
addImage()
3) 在 onCopySuccess
deferred.resolve(imageDetails)
4) 按以下方式使用:
ImageService.addImage(method).then(function(data){
window.alert('Final'+JSON.stringify(data));
$scope.user.image = data.src;
});
您还应该处理错误(有关详细信息,请参阅 angular 文档)。
您必须 return 来自 promise 的数据和 return 来自服务的 promise,然后将其与 .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));
});