在API调用后格式化的AngularJS指令

时间:2014-06-18 17:57:09

标签: javascript angularjs

我需要一个执行API请求的指令作为$ parsers函数。

<input type="text" name="referer" id="referer" ng-model="Subscribe.user.referer" check-referer>

我的指示看起来像

app.directive('checkReferer', [ 'subscriptionService', function( subscriptionService ) {
return {
        restrict: 'A',
        require: 'ngModel',
        link: function( scope, element, attrs, ngModel ) {
            ngModel.$parsers.unshift( function( viewValue ) {
                subscriptionService.checkReferer( viewValue )
                    .then(function( response ) {
                        if ( typeof response.data == 'object') {
                            ngModel.$setValidity('validReferer', true );
                            return viewValue;
                        }
                    });
             });
}])

为了便于阅读,我稍微缩短了代码。该服务非常简单(在服务中):

subscriptionService.checkReferer: function( email ) {
    var promise = $http.get( settings.ApiUrl + 'check-referer/' + email )
        .then( function( response ) {
            return response;
        }, function(response) {
            // error handling here
        })
    return promise;
 },

问题是:当我返回viewValue&#39;在加载了promise之后,$ modelValue没有改变,所以基本上promise不会改变通过ng-model传递给指令的Subscribe.user.referer。如果我返回的不同于承诺,一切都很好,所以问题在那里,不知道如何解决它:(

如果我将要作为属性更改的值传递给指令范围,我没有任何问题。但那不是我想做的事情:))

我对Angular并不是很熟悉,但我现在已经使用它一段时间了。我整个上午花了我自己试图找到答案。没运气。而且有点沮丧。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

为什么你没有将数据返回到你的指令中的原因是,服务花费时间将指令返回到指令之间,那时双向绑定已经由angular执行了。这是常见的问题之一异步调用。

因此,有多种解决方案,您可以使您的服务本质上同步

xhr.open(method, url, true);

查看此link

Nest 解决方案是 等到数据到达服务

// Make a remote request.
$http.get('some wonderful URL for a service').then(function (results) {
  superImportantInfo = results;

  semaphore = true;
});

while (!semaphore) {
  // We're just waiting.
}

另一个解决方案

var retrieveEventDetails = function(events) {
    // events is array

    var deferred = $q.defer();
    var promise = deferred.promise;

    var retrieveData = function(data) {
        return function(){      
            return $http({
                url: '/api/eventdetails',
                method: 'POST',
                data: {
                    event_number: data.number
                },
                isArray: true
            })
        }
    }

    deferred.resolve();

    return events.reduce(function(promise, single_event){
        return promise.then(retrieveData(single_event));
    }, promise);
}

希望这有帮助!