Angular JS:如何绑定到承诺 [英] Angular JS: how to bind to promises

查看:20
本文介绍了Angular JS:如何绑定到承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将承诺绑定到视图.我不知道你是否可以直接做到这一点,但这就是我正在尝试做的.知道我做错了什么吗?

注意:源代码有点人为设置超时并使用静态数据,但这是为了使代码更易于诊断.

JSFiddle 页面:http://jsfiddle.net/YQwaf/27/

解决方案:事实证明您可以直接绑定承诺.我的原始代码有两个问题:

  1. 使用 setTimeout() 而不是 angular 的 $timeout 是一个问题.Angular 不知道它需要在超时触发时刷新 UI(您可以使用 $scope.$apply 在 setTimeout 中解决这个问题,或者您可以只使用 $timeout )
  2. 绑定到返回承诺的函数是一个问题.如果它第二次被调用,它会做出另一个承诺.更好的是为承诺设置一个范围变量,并仅根据需要创建一个新的承诺.(就我而言,这是在国家/地区代码上调用 $scope.$watch)

HTML:

区域代码 国家代码<select ng:model="countryCode"><option value="US">美国</option><option value="CA">加拿大</option></select>

JS:

function addressValidationController($scope, $q, $timeout) {变量区域 = {我们: [{代码:'WI',name: '威斯康星州'},{代码:'MN',名称:'明尼苏达'}],CA:[{代码:'开',名称:'安大略'}]};函数 getRegions(countryCode) {console.log('getRegions:' + countryCode);var deferred = $q.defer();$超时(功能(){var countryRegions = region[countryCode];如果(国家/地区 === 未定义){console.log('解决空');deferred.resolve([]);} 别的 {console.log('解决');deferred.resolve(countryRegions);}}, 1000);返回 deferred.promise;};$scope.regions = [];//管理国家变更:$scope.$watch('countryCode', function(countryCode) {如果(angular.isDefined(国家代码)){$scope.regions = getRegions(countryCode);}别的 {$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:

  1. 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 )
  2. 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 = [];
        }
    });
}​

这篇关于Angular JS:如何绑定到承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆