角JS:如何绑定到承诺 [英] Angular JS: how to bind to promises
问题描述
我试图绑定一个承诺期。我不知道你是否能直接做的,但是这就是我试图做的。任何想法我做错了吗?
注:源与超时有点做作和使用静态的数据,但是这让code更容易诊断
编辑:的jsfiddle页: http://jsfiddle.net/YQwaf/27/
编辑:解决方法:原来您可以直接绑定的承诺。我有两个问题,我原来的code:
- 使用的setTimeout(),而不是角的$超时是一个问题。角不知道它需要刷新UI超时被触发时(你可以用$范围内解决这个问题。$应用里面的setTimeout,或者你可以用$超时)
- 绑定到返回的承诺是有问题的功能。如果被称为第二次,它使又一承诺。更好的是一个范围变量设置为承诺,只需要创建一个新的承诺。 (在我而言,这是呼吁国家code $范围。$表)
HTML
< DIV NG:控制器=addressValidationController>
地区code<选择NG:模型=区域codeNG:选项=R code作为getRegions r.name为R()。/>
国家code<选择NG:模型=乡村code><期权价值=US>美国< /选项><期权价值=CA>加拿大和LT; /选项&GT ;< /选择>
< / DIV>
JS:
函数addressValidationController($范围,$ Q){
VAR地区= {
美国:[{code:WI,名称:威斯康星},{code:MN,名称:'明尼苏达'}],
CA:[{code:ON,名称:安省'}]
};
$ scope.getRegions =功能(){
变种推迟= $ q.defer();
的setTimeout(函数(){
VAR countryRegions =地区[$ scope.country code];
的console.log(countryRegions);
如果(countryRegions ===未定义){
deferred.resolve([]);
}其他{
deferred.resolve(countryRegions);
}
},1000);
返回deferred.promise;
};
}
警告:这个答案是当它被写准确,但作为1.2角模板引擎并不透明地处理的承诺! - @Malvolio 的
块引用>是模板引擎(和前pressions)处理的承诺透明,但我的承诺分配给作用域属性控制器,而不是每次调用返回一个新的承诺的函数(我认为这是你的问题,因为一个新的承诺将返回每次)解决承诺将丢失。
的jsfiddle: http://jsfiddle.net/YQwaf/36/
HTML
< DIV NG:控制器=addressValidationController>
地区code<选择NG:模型=区域codeNG:选项=R code作为r.name在地区R/>
国家code<选择NG:模型=乡村code><期权价值=US>美国< /选项><期权价值=CA>加拿大和LT; /选项&GT ;< /选择>
< / DIV>JS:
函数addressValidationController($范围,$ Q $超时){
VAR地区= {
美国:[{
code:WI,
名称:威斯康星},
{
code:MN,
名称:'明尼苏达'}],
CA:[{
code:ON,
名称:安省'}]
}; 功能getRegions(国家code){
的console.log('getRegions:+国家code);
变种推迟= $ q.defer();
$超时(函数(){
VAR countryRegions =地区[全国code];
如果(countryRegions ===未定义){
的console.log('解决空');
deferred.resolve([]);
}其他{
的console.log('决心');
deferred.resolve(countryRegions);
}
},1000);
返回deferred.promise;
}; $ scope.regions = []; //管理国家的变化:
$范围。$腕表('全国code',函数(国家code){
如果(angular.isDefined(国家code)){
$ scope.regions = getRegions(国家code);
}
其他{
$ scope.regions = [];
}
});
}I am trying to bind a promise to a view. I don't know if you can do that directly, but that's what I'm attempting to do. Any ideas what I am doing wrong?
Note: the source is a little contrived with the timeout and uses static data, but that's to make the code easier to diagnose.
EDIT: JSFiddle Page: http://jsfiddle.net/YQwaf/27/
EDIT: SOLUTION: It turned out you can directly bind promises. I had two problems with my original code:
- Using setTimeout() instead of angular's $timeout was a problem. Angular doesn't know it needs to refresh the UI when the timeout is triggered ( You could solve this with $scope.$apply inside setTimeout, or you can just use $timeout )
- Binding to a function that returned a promise was a problem. If it gets called a second time, it makes yet another promise. Better is to set a scope variable to the promise and only create a new promise as needed. (In my case, this was calling $scope.$watch on the Country Code)
HTML:
<div ng:controller="addressValidationController"> Region Code <select ng:model="regionCode" ng:options="r.code as r.name for r in getRegions()"/> Country Code<select ng:model="countryCode"><option value="US">United States</option><option value="CA">Canada</option></select> </div>
JS:
function addressValidationController($scope, $q) { var regions = { US: [{code: 'WI',name: 'Wisconsin'}, {code: 'MN',name: 'Minnesota'}], CA: [{code: 'ON',name: 'Ontario'}] }; $scope.getRegions = function () { var deferred = $q.defer(); setTimeout(function () { var countryRegions = regions[$scope.countryCode]; console.log(countryRegions); if(countryRegions === undefined) { deferred.resolve([]); } else { deferred.resolve(countryRegions); } }, 1000); return deferred.promise; }; }
解决方案WARNING: this answer was accurate when it was written, but as of 1.2 the Angular template engine does not handle promises transparently! -- @Malvolio
Yes the template engine (and expressions) handle promises transparently, but I would assign the promise to a scope property in the controller and not call everytime a function that returns a new promise (I think it's your problem, resolved promise is lost because a new promise is returned everytime).
JSFiddle: http://jsfiddle.net/YQwaf/36/
HTML:
<div ng:controller="addressValidationController"> Region Code <select ng:model="regionCode" ng:options="r.code as r.name for r in regions"/> Country Code<select ng:model="countryCode"><option value="US">United States</option><option value="CA">Canada</option></select> </div>
JS:
function addressValidationController($scope, $q, $timeout) { var regions = { US: [{ code: 'WI', name: 'Wisconsin'}, { code: 'MN', name: 'Minnesota'}], CA: [{ code: 'ON', name: 'Ontario'}] }; function getRegions(countryCode) { console.log('getRegions: ' + countryCode); var deferred = $q.defer(); $timeout(function() { var countryRegions = regions[countryCode]; if (countryRegions === undefined) { console.log('resolve empty'); deferred.resolve([]); } else { console.log('resolve'); deferred.resolve(countryRegions); } }, 1000); return deferred.promise; }; $scope.regions = []; // Manage country changes: $scope.$watch('countryCode', function(countryCode) { if (angular.isDefined(countryCode)) { $scope.regions = getRegions(countryCode); } else { $scope.regions = []; } }); }
这篇关于角JS:如何绑定到承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!