承诺在表达中找到。不推荐在Angular表达式中自动展开promise

时间:2014-02-10 15:16:19

标签: javascript angularjs expression promise jquery-chosen

我正在尝试创建一个新的AngularJS项目,但是我遇到了一些错误:(

这是我的应用和控制器;

var app = angular.module('myApp', ['localytics.directives'])
    .config(['$parseProvider', function ($parseProvider) {
        return $parseProvider.unwrapPromises(true);
    }])
    .controller('myController', function ($scope, $http, $q, $timeout) {
    var simulateAjax;
    simulateAjax = function (result) {
        var deferred, fn;
        deferred = $q.defer();
        fn = function () {
            return deferred.resolve(result);
        };
        $timeout(fn, 1000);
        return deferred.promise;
    };

    $scope.ListOfTags = function () {
        $http({
            method: 'Post',
            url: 'FillCategories'
        }).success(function (data, status, headers, config) {
            $scope.optionsFromQuery = (function () {
                return simulateAjax(data);
            })();
        }).error(function (data, status, headers, config) {
            $scope.message = 'Unexpected Error';
        });
    }
    $scope.directiveOptions = {
        no_results_text: "Error"
    };
});
<div data-ng-click="ListOfTags()"></div>

我使用Chosen.js如下:

<select id="select_{{ item.RowId }}" ng-model="chosenModel" chosen="directiveOptions" ng-options="item._categoryId as item._categoryName for item in optionsFromQuery" style="width:200px;">
    <option value="">Select</option>
</select>

当我尝试获取类别时,它正在运行,但抛出以下异常(打破了Angular应用程序):

  

[$ parse]在表达式optionsFromQuery中找到的承诺。自动   不推荐在Angular表达式中展开promise。

第二次尝试获取类别似乎无效。

造成这种情况的原因是什么?

2 个答案:

答案 0 :(得分:1)

您需要将promise的结果保存到作用域的单独变量中。 (Angular目前单独执行此操作,但它将改变该行为。这意味着模板将在显示结果之前等待承诺完成)

.controller('myController', function ($scope, $http) {
    // old behavior, automatic unwrapping
    $scope.data = $http.get('someUrl');

    // new behavior, no automatic unwrapping
    $http.get('someUrl').success(function(data) {
        scope.data = data;
    });
});

答案 1 :(得分:1)

从你的代码:

simulateAjax是一个函数返回promise。接下来,您在success回调中调用此方法。

因此ListOfTags也会返回承诺。

我会将其实现为 chain 承诺,而不是将success回调与then()混合

  • 您可以将它们链接起来以创建代码流
  • 错误传播,因此您可以在链的末尾捕获它
  • 实际上,它们很像 众所周知的try-catch-finally子句的异步等价物。

实施例

$scope.ListOfTags = function() {
        var myHttp = $http({method: 'Post', url: 'FillCategories'});

              myHttp.then(function (result) {
                     return simulateAjax(data); 
                    }).then(function (result) {
                       return result;                            
                    }, function (result) {
                        alert("Error: No data returned");                           
                    });         
    }

如果你有兴趣改变你的代码尝试遵循方式(但我仍然喜欢大写):

 $scope.ListOfTags = function() {
        $http({
            method: 'Post',
            url: 'FillCategories'
        }).success(function (data, status, headers, config) {
            $scope.optionsFromQuery = (function () {
                return simulateAjax(data).then(function (result) {
                       return result;                            
                    }, function (result) {
                        alert("Error: No data returned");
                        return null;
                    });
            })();
        }).error(function (data, status, headers, config) {
            $scope.message = 'Unexpected Error';
        });
    }