cil*_*hex 43 javascript angularjs
我正在观看这个 AngularJS教程,该教程描述了如何使用Angular资源挂钩到Twitter.(视频教程)以下是示例控制器中设置的资源:
$scope.twitter = $resource('http://twitter.com/:action',
{action: 'search.json', q: 'angularjs', callback: 'JSON_CALLBACK'},
{get: {method: 'JSONP'}});
Run Code Online (Sandbox Code Playgroud)
该教程显示有几种方法可以使用get
调用从资源中恢复数据.第一种方法是将回调传递给get函数.在ajax请求返回后,将使用结果调用回调:
$scope.twitter.get(function(result) {
console.log('This was the result:', result);
});
Run Code Online (Sandbox Code Playgroud)
我理解这种方法.这对我来说非常有意义.资源代表Web上可以获取数据的位置,get
只需对URL进行ajax调用,返回json,并使用json调用回调函数.这个result
参数是json.
这对我来说很有意义,因为很明显这是一个异步调用.也就是说,在引擎盖下,ajax调用会触发,并且调用后的代码不会被阻止,它会继续执行.然后在稍后的某个不确定点,当xhr成功时,调用回调函数.
然后教程显示了一个看起来更简单的不同方法,但我不明白它是如何工作的:
$scope.twitterResult = $scope.twitter.get();
Run Code Online (Sandbox Code Playgroud)
我假设下面的xhr get
必须是异步的,但在这一行中我们将get
调用的返回值赋给变量,就像它同步返回一样.
不理解这个我错了吗?怎么可能?我觉得它很有效,但是我觉得它不行.
我的理解是get
可以返回的东西,而在其下方XHR熄灭和流程异步,但如果你自己遵循的代码示例,你会看到,$scope.twitterResult
在执行任何后续行之前得到的实际Twitter的内容.例如,如果您console.log($scope.twitterResult)
在该行之后立即写入,您将在控制台中看到来自twitter的结果,而不是稍后替换的临时值.
更重要的是,因为这是可能的,我如何编写利用相同功能的Angular服务?除了ajax请求之外,还有其他类型的数据存储需要可以在JavaScript中使用的异步调用,我希望能够以这种方式同步编写代码.例如,IndexedDB.如果我能够了解Angular的内置资源是如何做到的,我会试一试.
pko*_*rce 63
$ resource不是同步的,尽管这种语法可能表明它是:
$scope.twitterResult = $scope.twitter.get();
Run Code Online (Sandbox Code Playgroud)
这里发生的是调用AngularJS后twitter.get()
,会立即返回结果为空数组.然后,当异步调用完成并且实际数据从服务器到达时,阵列将更新数据.AngularJS将简单地保留对返回的数组的引用,并在数据可用时填充它.
以下是$ magic实现的片段,其中发生了"魔术":https://github.com/angular/angular.js/blob/master/src/ngResource/resource.js#L372
这也在$ resource文档中描述:
重要的是要意识到调用$ resource对象方法会立即返回一个空引用(取决于对象或数组
isArray
).从服务器返回数据后,将使用实际数据填充现有引用.这是一个有用的技巧,因为通常将资源分配给模型,然后由视图呈现.具有空对象导致无渲染,一旦数据从服务器到达,则对象用数据填充,并且视图自动重新呈现其自身显示新数据.这意味着在大多数情况下,永远不必为动作方法编写回调函数.
$ q也可以做到这一点.您可以使用以下内容将普通对象转换为"延迟值":
var delayedValue = function($scope, deferred, value) {
setTimeout(function() {
$scope.$apply(function () {
deferred.resolve(value);
});
}, 1000);
return deferred.promise;
};
Run Code Online (Sandbox Code Playgroud)
然后在控制器中使用它,以获得与$ scope.twitter.get()在OP示例中所做的类似的效果
angular.module('someApp', [])
.controller('someController', ['$scope', '$q', function($scope, $q) {
var deferred = $q.defer();
$scope.numbers = delayedValue($scope, deferred, ['some', 'numbers']);
}]);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
42006 次 |
最近记录: |