Javascript 角度工厂承诺内的可变范围
我无法将工厂中的角度承诺数据返回控制器。 在这个例子中Javascript 角度工厂承诺内的可变范围,javascript,angularjs,angularjs-scope,angular-promise,Javascript,Angularjs,Angularjs Scope,Angular Promise,我无法将工厂中的角度承诺数据返回控制器。 在这个例子中 更新:函数(staffList){ //获取本地上次更新的时间戳 var lastUpdatedLocal=“”; var lastUpdateRemote=“”; 对于(i=0;ilastUpdatedLocal){ lastUpdatedLocal=StatfList[i]。输入日期; } } //获取远程上次更新的时间戳 var promise=$http.get('REMOTE\u API\u CALL') .success(函数
更新:函数(staffList){
//获取本地上次更新的时间戳
var lastUpdatedLocal=“”;
var lastUpdateRemote=“”;
对于(i=0;ilastUpdatedLocal){
lastUpdatedLocal=StatfList[i]。输入日期;
}
}
//获取远程上次更新的时间戳
var promise=$http.get('REMOTE\u API\u CALL')
.success(函数(数据、状态、标题、配置){
return lastUpdateRemote=数据[0]。输入日期;
}).然后(功能(响应){
返回响应。数据[0]。输入日期;
});
console.log(promise);
}
我想过滤本地数据以获得本地时间戳,将其与远程时间戳进行比较,并指示控制器在本地时间戳小于远程时间戳时重新下载所有数据
我正在过滤本地数据,并得到预期的结果。我似乎被承诺困住了。我可以在.success或.then方法中注销筛选后的远程数据,但没有太多运气返回承诺中的值。我知道这里可能存在变量范围的问题
另外,我是否最好将一个布尔值从工厂返回到控制器(我是否应该更新?真/假),或者是一个带有本地和远程时间戳数据的小obj,然后让控制器决定从那里做什么
提前感谢。这里是我所拥有的关于如何实现这一点的最佳示例。我对你的控制器和工厂做了一些假设。请注意,您需要向工厂注入$q以使用延迟。这就是我在我的应用程序中的操作方式
/*
注意:请确保在开始之前向工厂注入$q
这在我的示例中,让我们假设
工厂看起来是这样的:
*/
app.factory('mySweetFactory',['$q',function$q){
返回{
//你可能有很多其他的方法,比如
//这是你们工厂的。
myothermethod:函数(argument1,argument2){
/*这里有一些代码*/
},
更新:函数(staffList){
//创建一个新的延迟对象
var deferred=$q.deferred();
//获取本地上次更新的时间戳
var lastUpdatedLocal=“”;
对于(i=0;ilastUpdatedLocal){
lastUpdatedLocal=StatfList[i]。输入日期;
}
}
//调用远程api
$http.get('REMOTE\u API\u CALL')。然后(函数(响应){
//获取上次更新的远程文件
//从回应开始的时间
var lastUpdatedRemote=response.data[0]。输入日期;
//检查本地或远程是否较大
//您可能需要修改此选项
//取决于日期时间格式。
//我假设一个划时代的弦。
if(lastUpdatedRemote>lastUpdatedLocal)
{
//解决延迟和返回问题
//这些数据将被删除,以便控制器可以
//使用它来更新视图
延迟。解析(响应。数据);
}否则{
//既然我们什么都不需要做,
//拒绝延期付款
拒绝();
});
//从延迟对象返回承诺
//马上。我们最终也会
//解决或拒绝它,但在一开始,它
//将处于挂起状态。
回报。承诺;
}
};
}]);
app.controller('mySweetController',['mySweetFactory',function(mySweetFactory){
$scope.doUpdate=函数(){
更新($scope.staffList)。然后(函数(newStaffList){
//承诺已解决。列表需要更新!
$scope.staffList=newStaffList;
},函数(){
//承诺被拒绝。无需更新!
});
};
}]);
两个问题。我们可以查看您的范围/视图吗?您是否使用ng repeat作为staffList?如果是这样,并且如果您要到服务器获取响应,那么您是否可以使用响应更新staffList?通常,我只需更新绑定到ng repeat的任何变量,然后让angular执行脏检查以查看If需要更新dom。这是由用户通过刷新操作触发的还是在后台运行的?我已经对所有这些进行了重构,因此我没有控制器的示例。当时我希望服务返回带有时间戳的对象,甚至只是返回true/false和控件ler会处理布尔响应。我使用Ionic的collection repeat来提高性能。用户“拉动刷新”这就是为什么我要检查时间戳,而不是下载所有数据并将其重新分配给作用域。如果数据没有变化,那么这样做没有意义。我别无选择,最终只能将承诺返回给控制器。我很高兴。很高兴它有用。
update: function (staffList) {
// get local last updated timestamp
var lastUpdatedLocal = "";
var lastUpdatedRemote = "";
for (i=0; i < staffList.length; i++) {
// get largest (most recent) timestamp
if(staffList[i].entry_date > lastUpdatedLocal) {
lastUpdatedLocal = staffList[i].entry_date;
}
}
// get remote last updated timestamp
var promise = $http.get('REMOTE_API_CALL')
.success(function(data, status, header, config) {
return lastUpdatedRemote = data[0].entry_date;
}).then(function(response) {
return response.data[0].entry_date;
});
console.log(promise);
}
/*
NOTE: make sure to inject $q into your factory before
this. For the purposes of my example, let's assume your
factory looks like this:
*/
app.factory('mySweetFactory', ['$q', function($q) {
return {
// You probably have a bunch of other methods like
// this one in your factory.
myothermethod: function(argument1, argument2) {
/* some code here */
},
update: function (staffList) {
// Create a new deferred object
var deferred = $q.defer();
// get local last updated timestamp
var lastUpdatedLocal = "";
for (i=0; i < staffList.length; i++) {
// get largest (most recent) timestamp
if(staffList[i].entry_date > lastUpdatedLocal) {
lastUpdatedLocal = staffList[i].entry_date;
}
}
// Make a call to the remote api
$http.get('REMOTE_API_CALL').then(function(response) {
// Get the remote last updated
// time from the response
var lastUpdatedRemote = response.data[0].entry_date;
// Check if local or remote is larger
// You probably need to modify this
// depending on your datetime formatting.
// I am assuming an epoch string.
if(lastUpdatedRemote > lastUpdatedLocal)
{
// Resolve the deferred and return
// the data so that the controller can
// use it to update the view
deferred.resolve(response.data);
} else {
// Since we don't need to do anything,
// reject the deferred
deferred.reject();
});
// Return the promise from the deferred object
// immediately. We will eventually either
// resolve or reject it, but at the start, it
// will be in a pending state.
return deferred.promise;
}
};
}]);
app.controller('mySweetController', ['mySweetFactory', function(mySweetFactory){
$scope.doUpdate = function() {
mySweetFactory.update($scope.staffList).then(function(newStaffList) {
// Promise was resolved. List needs updating!
$scope.staffList = newStaffList;
}, function(){
// Promise was rejected. No update needed!
});
};
}]);