如何在 AngularJS 中将承诺传递给控制器
How to pass a promise to a controller in AngularJS
我无法理解承诺。我有一个函数 $scope.startJob
,当被调用时,它会在 SegmentsService
中调用 areThereAvailableSegments
。我的想法是 areThereAvailableSegments
应该 return true 或 false,这样我就可以在控制器中处理这种行为,但不确定该怎么做。
areThereAvailableSegments
调用 getSegments()
,后者从数据库请求文本段。 getSegments
return 是一个承诺,我正在尝试用 areThereAvailableSegments
中的 .then
来处理这个承诺,但不确定如何传递给控制器。
这是我的 Segments 工厂,return 是 $resource
对象,segmentsfactory.js
:
angular.module('appApp')
.factory('SegmentsFactory', function ($resource) {
return $resource('http://localhost:3000/api/v1/segments/:id');
});
这是我的 Segments 服务,segmentsservice.js
:
angular.module('appApp')
.service('SegmentsService', function (SegmentsFactory) {
// gets segments from mongo
this.getSegments = function(jobId) {
return SegmentsFactory.query({ job_id: jobId }).$promise;
};
// should return true/false if there are available segments
this.areThereAvailableSegments = function(jobId) {
var dump = [];
// queries for all segments
this.getSegments(jobId)
.then(function(segments) {
// dumps segments status in a temp array
for (var i = 0; i < segments.length; i++) {
dump.push(segments[i].status);
}
// returns true if there is an 'available' in the temp array
if (dump.indexOf('available') >= 0) {
return true;
} else {
return false;
}
});
};
});
这是我的控制器,main.js
:
$scope.startJob = function() {
if (SegmentsService.areThereAvailableSegments(jobId)) {
console.log('there are available segments, then trigger texteditor');
} else {
console.log('no segments to translate');
}
};
执行时,控制台显示"no segments to translate",因为SegmentsService
不是return真或假。
如何解决?
没有理由同时拥有服务和工厂。删除工厂并将该代码移至服务中。至于你的问题,你将不得不使用 $q 模块来 return 一个承诺。 https://docs.angularjs.org/api/ng/service/$q
this.areThereAvailableSegments = function(jobId) {
var dump = [];
var deferred = $q.deferred;
// queries for all segments
this.getSegments(jobId)
.then(function(segments) {
// dumps segments status in a temp array
for (var i = 0; i < segments.length; i++) {
dump.push(segments[i].status);
}
// returns true if there is an 'available' in the temp array
if (dump.indexOf('available') >= 0) {
deferred.resolve(true);
} else {
deferred.resolve(false);
}
});
return deferred.promise;
};
然后您将不得不在控制器中处理承诺。
函数 areThereAvailibleSegments
也应该 return 一个承诺。
然后在你的控制器中你有一个 then case 并且在那里有你的 if-else。
this.areThereAvailableSegments = function(jobId) {
var dump = [];
// queries for all segments
return this.getSegments(jobId) //Return here
.then(function(segments) {
// dumps segments status in a temp array
for (var i = 0; i < segments.length; i++) {
dump.push(segments[i].status);
}
// returns true if there is an 'available' in the temp array
if (dump.indexOf('available') >= 0) {
return true;
} else {
return false;
}
});
};
由于您的成功函数 return 为真或假,areThereAvailibleSegments
函数的承诺将具有该布尔值。
然后在你的控制器中:
SegmentsService.areThereAvailableSegments(jobId).then(function(available){
if (available) {
console.log('there are available segments, then trigger texteditor');
} else {
console.log('no segments to translate');
}
});
我会这样设置...在你的工厂完成承诺,然后在控制器中调用数据。
在您的服务 js 中:
.factory('SegmentsFactory', function ($resource) {
var APIRequest = {};
APIRequest.getSegments = function(id){
segmentsAPI = $resource('http://localhost:3000/api/v1/segments/'+id'', ;
return segmentAPI.get().$promise.then(function(segments){
console.log(segments);
return segments;
});
};
return APIRequest;
}]);
然后在你的控制器中:
var dump = [];
$scope.startJob = function() {
if (SegmentsService.areThereAvailableSegments) {
APIRequest.getSegments($scope.id).then(function(data){
if (data.error){
//error stuff here
} else {
if (data.segments.length > 0){
for(var i=0; i < segments.length; i++){
console.log(segments);
dump.push(segments[i].status);
}
};
我无法理解承诺。我有一个函数 $scope.startJob
,当被调用时,它会在 SegmentsService
中调用 areThereAvailableSegments
。我的想法是 areThereAvailableSegments
应该 return true 或 false,这样我就可以在控制器中处理这种行为,但不确定该怎么做。
areThereAvailableSegments
调用 getSegments()
,后者从数据库请求文本段。 getSegments
return 是一个承诺,我正在尝试用 areThereAvailableSegments
中的 .then
来处理这个承诺,但不确定如何传递给控制器。
这是我的 Segments 工厂,return 是 $resource
对象,segmentsfactory.js
:
angular.module('appApp')
.factory('SegmentsFactory', function ($resource) {
return $resource('http://localhost:3000/api/v1/segments/:id');
});
这是我的 Segments 服务,segmentsservice.js
:
angular.module('appApp')
.service('SegmentsService', function (SegmentsFactory) {
// gets segments from mongo
this.getSegments = function(jobId) {
return SegmentsFactory.query({ job_id: jobId }).$promise;
};
// should return true/false if there are available segments
this.areThereAvailableSegments = function(jobId) {
var dump = [];
// queries for all segments
this.getSegments(jobId)
.then(function(segments) {
// dumps segments status in a temp array
for (var i = 0; i < segments.length; i++) {
dump.push(segments[i].status);
}
// returns true if there is an 'available' in the temp array
if (dump.indexOf('available') >= 0) {
return true;
} else {
return false;
}
});
};
});
这是我的控制器,main.js
:
$scope.startJob = function() {
if (SegmentsService.areThereAvailableSegments(jobId)) {
console.log('there are available segments, then trigger texteditor');
} else {
console.log('no segments to translate');
}
};
执行时,控制台显示"no segments to translate",因为SegmentsService
不是return真或假。
如何解决?
没有理由同时拥有服务和工厂。删除工厂并将该代码移至服务中。至于你的问题,你将不得不使用 $q 模块来 return 一个承诺。 https://docs.angularjs.org/api/ng/service/$q
this.areThereAvailableSegments = function(jobId) {
var dump = [];
var deferred = $q.deferred;
// queries for all segments
this.getSegments(jobId)
.then(function(segments) {
// dumps segments status in a temp array
for (var i = 0; i < segments.length; i++) {
dump.push(segments[i].status);
}
// returns true if there is an 'available' in the temp array
if (dump.indexOf('available') >= 0) {
deferred.resolve(true);
} else {
deferred.resolve(false);
}
});
return deferred.promise;
};
然后您将不得不在控制器中处理承诺。
函数 areThereAvailibleSegments
也应该 return 一个承诺。
然后在你的控制器中你有一个 then case 并且在那里有你的 if-else。
this.areThereAvailableSegments = function(jobId) {
var dump = [];
// queries for all segments
return this.getSegments(jobId) //Return here
.then(function(segments) {
// dumps segments status in a temp array
for (var i = 0; i < segments.length; i++) {
dump.push(segments[i].status);
}
// returns true if there is an 'available' in the temp array
if (dump.indexOf('available') >= 0) {
return true;
} else {
return false;
}
});
};
由于您的成功函数 return 为真或假,areThereAvailibleSegments
函数的承诺将具有该布尔值。
然后在你的控制器中:
SegmentsService.areThereAvailableSegments(jobId).then(function(available){
if (available) {
console.log('there are available segments, then trigger texteditor');
} else {
console.log('no segments to translate');
}
});
我会这样设置...在你的工厂完成承诺,然后在控制器中调用数据。
在您的服务 js 中:
.factory('SegmentsFactory', function ($resource) {
var APIRequest = {};
APIRequest.getSegments = function(id){
segmentsAPI = $resource('http://localhost:3000/api/v1/segments/'+id'', ;
return segmentAPI.get().$promise.then(function(segments){
console.log(segments);
return segments;
});
};
return APIRequest;
}]);
然后在你的控制器中:
var dump = [];
$scope.startJob = function() {
if (SegmentsService.areThereAvailableSegments) {
APIRequest.getSegments($scope.id).then(function(data){
if (data.error){
//error stuff here
} else {
if (data.segments.length > 0){
for(var i=0; i < segments.length; i++){
console.log(segments);
dump.push(segments[i].status);
}
};