角JS:如何绑定到承诺(Angular JS: how to bind to promises)

2019-06-18 14:34发布

我想绑定的承诺视图。 我不知道你是否能直接做的,但是这就是我试图做的。 任何想法我做错了吗?

注:源与超时有点做作和使用静态数据,但这是为了使代码更容易诊断。

编辑:的jsfiddle页: http://jsfiddle.net/YQwaf/27/

编辑:解:原来,你可以直接绑定的承诺。 我有两个问题,我原来的代码:

  1. 使用的setTimeout(),而不是角的$超时是一个问题。 角不知道它需要刷新UI超时被触发时(你可以用$范围解决这个问题。$应用里面的setTimeout,或者你可以用$超时)
  2. 绑定到返回的承诺的功能是一个问题。 如果它被称为第二次,这让另一个承诺。 更好的是一个范围变量设置为承诺,只需要创建一个新的承诺。 (在我的情况,这是调用$范围。$观看的国家或地区代码)

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;
    };
}

Answer 1:

警告 :这个答案是当它被写准确,但为1.2角模板引擎并不透明地处理的承诺! - @Malvolio

是的模板引擎(表达式)处理的承诺透明,但我的承诺分配给scope属性控制器,而不是调用每次返回一个新的承诺(我认为这是你的问题的功能,解决了承诺的丢失,因为一个新的承诺返回每次)。

的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 = [];
        }
    });
}​


Answer 2:

由于角1.2的, 你不能使用模板的承诺直接了 。
相反,你需要把结果为$scopethen ,像往常一样,没有什么神奇。

作为临时解决办法拿到老的行为,你可以调用

$parseProvider.unwrapPromises(true)

但是这个功能将在稍后删除,所以不依赖于它。



Answer 3:

由于角1.3 - $parseProvider.unwrapPromises(true) 将不再起作用 。

相反,你应该直接拆开包装的承诺:

myApiMethod().then(function(value){
    $scope.item = value; 
});

需要注意的是承诺的解包仍然会以ngResource照常上班。



Answer 4:

久违的范围变量保存列表应该足够的参考。

function addressValidationController($scope,$timeout) {
    var regions = {
        US: [{code: 'WI',name: 'Wisconsin'}, {code: 'MN',name: 'Minnesota'}], 
        CA: [{code: 'ON',name: 'Ontario'}]
    };

    $scope._regions = [];

    $scope.getRegions = function () {

        $timeout(function () {
            var countryRegions = regions[$scope.countryCode];
            console.log(countryRegions);
            if(countryRegions === undefined) {
                $scope._regions = []
            } else {
                $scope._regions = countryRegions
            }
        }, 1000);

        return $scope._regions;
    };
}


文章来源: Angular JS: how to bind to promises