Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 异步调用函数的角度问题_Angularjs_Angularjs Directive - Fatal编程技术网

Angularjs 异步调用函数的角度问题

Angularjs 异步调用函数的角度问题,angularjs,angularjs-directive,Angularjs,Angularjs Directive,我正在使用一个Angular指令,它从localStorage加载JSON数据 使用localStorage.getItem(id)很容易做到这一点,但现在我正试图通过API调用(这反过来又从数据库中提取)使其工作 我的Angular factory代码正常工作,http请求正常工作,但在指令代码中有一个\u handleAsyncLoad()函数正在抛出我。换句话说,我正试图使用内置的承诺来实现从API层返回的序列化对象 例如/我已经编写了新的匿名函数,\u getItemFromAPI:,但

我正在使用一个
Angular指令
,它从
localStorage
加载JSON数据

使用
localStorage.getItem(id)
很容易做到这一点,但现在我正试图通过API调用(这反过来又从数据库中提取)使其工作

我的Angular factory代码正常工作,http请求正常工作,但在指令代码中有一个
\u handleAsyncLoad()
函数正在抛出我。换句话说,我正试图使用内置的承诺来实现从API层返回的
序列化
对象

例如/我已经编写了新的匿名函数,
\u getItemFromAPI:
,但不确定是否需要使用
\u handleAsyncLoad:
函数。如果没有,最好的方法是什么,以确保在返回我的
序列化
对象之前填充数据

angular.module('ui.dashboard')
.factory('DashboardState'、['$log'、'$q'、'dashboardcontext'、'$rootScope',函数($log、$q、dashboardcontext、$rootScope){
函数仪表板状态(存储、id、哈希、widgetDefinitions、stringify){
这个.存储=存储;
this.id=id;
this.hash=hash;
this.widgetDefinitions=widgetDefinitions;
this.stringify=stringify;
}
DashboardState.prototype={
加载:函数(仪表板ID){
如果(!this.storage){
返回null;
}
var序列化;
//从存储器中获取仪表板布局
if(dashboardId!=null&&dashboardId!=未定义){
//serialized=this.storage.getItem(dashboardId);//更旧、更简单的方法
serialized=this.\u getItemFromAPI($rootScope);//新方法,通过API拉取数据!
}
否则{
//恢复到原始行;请参见主控制器的仪表板选项
序列化=this.storage.getItem(this.id);
}
如果(序列化){
//检查承诺
if(angular.isObject(序列化)){
返回此。\u handleAsyncLoad(序列化);
}
//否则处理同步负载
返回此。\u handleSyncLoad(序列化);
}否则{
返回null;
}
},         
_getItemFromAPI:函数($rootscope){
//将仪表板持久化到存储的服务器端API调用-2015年3月9日BM:
var sid=$rootScope.rageSessionVars.sessionID;
var userid=$rootScope.rageSessionVars.userid;
var dashboardId=this.id;
dashboardcontext.getDashboardImage(sid、userid、dashboardId)。然后(函数(数据){
如果(data.status==“失败”){
window.alert(“检索仪表板失败。”+数据.messages);
返回false;
}
否则{
返回数据;
}
});
返回新承诺(函数(解析、拒绝){});
},
_handleSyncLoad:函数(序列化){
变量反序列化,结果=[];
如果(!序列化){
返回null;
}
if(this.stringify){
尝试{//反序列化字符串
反序列化=JSON.parse(序列化);
}捕获(e){
//错误的JSON,记录警告并返回
$log.warn('序列化的仪表板状态格式不正确,无法分析:',已序列化);
返回null;
}
}
否则{
反序列化=序列化;
}     
//缓存小部件
var savedWidgetDefs=反序列化的.widgets;
返回结果;
},
_handleAsyncLoad:功能(承诺){
var self=这个;
var deferred=$q.deferred();
我保证,那么(
//成功
功能(res){
var结果=自身。\u handleSyncLoad(res);
如果(结果){
延迟。解决(结果);
}否则{
延迟。拒绝(结果);
}
},
//失败
功能(res){
延期。拒绝(res);
}
);
回报。承诺;
}
};
返回仪表板状态;

}]);一旦进行了异步操作,就应该使公共API也异步,即使在某些或大多数情况下是同步的。那么用户的API是一致的

将同步调用转换为承诺,而不是“检查承诺”

然后,您的
load
函数可以简化为以下内容(为了简洁起见,我留下了一些细节,但您应该了解更广泛的概念):

请注意,我假设
\u getItemFromAPI()
返回一个承诺(在您的情况下,它不会),因此它将如下所示:

function _getItemFromAPI(){

  // ...

  // this "return" is important! it returns the promise generated by $http
  return $http({...}).then(function(response){
    return response.data;
  })
}
这使得
load
的使用无论是同步还是异步都是一致的:

dashboardSvc.load(444).then(function(dashboardData){
  $scope.dashboard = dashboardData;
});

@鲍勃,还没还。应该是
返回dashboardcontext.getDashboardImage()…
我在上面添加了
getDashboardImage
函数作为参考;但是如果我理解正确,你是说承诺不是从
\u getItemFromAPI()
@bob返回的,是的。我可以看到
getDashboardImage
返回一个承诺,因为它后面跟着
。然后
,但您还需要
返回该
的承诺。然后
我更新了我的
加载:
函数,但在
处得到一个错误,返回此值。\u handleSyncLoad(数据)。如果在
return\u getItemFromAPI()上解决了承诺,则该问题似乎超出了范围。然后
@bob,编辑问题以适应给定的建议不是一个好主意-这会使答案/评论对未来用户来说毫无意义。请恢复原样。也。很难理解“出错”的具体含义。
是否定义了此.\u handleSyncLoad
?在任何情况下,你可能有比你的问题范围更广泛的问题
dashboardSvc.load(444).then(function(dashboardData){
  $scope.dashboard = dashboardData;
});