2

Моя цель , чтобы показать имя пользователя, которое необходимо манипулировать на веб-странице. Маршрутизация должна выполняться централизованно в сервисе (MasterDataService). Я хочу использовать переменную области видимости на экране, которая определена в контроллере. Контроллер вызывает централизованный сервис. Служба вызывает другую службу, которая вызывает внутренний сервер, обрабатывает имя пользователя и возвращает результат обратно контроллеру. Результатом должен быть только объект JSON, а не разрешенный запрос (отложить и обещать).Получение только объекта от асинхронного вызова

Веб-страница -> страница контроллер-> Централизованная сервис-> абонентское -> и путь назад

Я делаю это, как этот

веб-страницы

<div id="usercontainer" ng-show="currentUser" class="ng-hide"> 
    Hallo, {{currentUser.currentUserName}}.<br /> 
    (<a href="#/logout">Abmelden</a>) 
</div> 

контроллер

$scope.getCurrentUser = function() { 

    $scope.currentUser = MasterDataService.getCurrentUser(); 
    $log.debug($scope.currentUser); // <-- this is empty afterwards (undefined) 
} 

MasterDataSer вице-

getCurrentUser: function() { 

        var promise = UserService.getCurrentUser(); 
        promise.then(function (resolvedResponse) { 
         $log.debug("MasterDataService.getCurrentUser.start"); 
         var currentUser = resolvedResponse.data; 

         var userLabel = currentUser.Email; 
         if (currentUser.Salutation && (currentUser.LastName !== "" && currentUser.LastName !== undefined && currentUser.LastName !== null)) { 
          userLabel = currentUser.Salutation.Name + " " + currentUser.LastName; 
          if (currentUser.Title) { 
           userLabel = currentUser.Salutation.Name + " " + currentUser.Title.Name + " " + currentUser.LastName; 
          } 
         } 
         currentUser.currentUserName = userLabel; 
         return currentUser; 

        }, function (resolvedResponse) { 
         $log.debug("MasterDataService.getCurrentUser.error"); 
        }, function (resolvedResponse) { 
         $log.debug("MasterDataService.getCurrentUser.notification"); 
        }); 
       } 

UserService

 getCurrentUser: function (optionsData) { 
      $log.debug("UserService.getCurrentUser.start"); 

      var promise = $http({ 
       method: 'GET', 
       url: '/api/User' 
      }).then(function (response) { 

       var deferred = $q.defer(); 
       $log.debug("UserService.changeOptions.success.status: " + response.status); 
       if (response.status == 200) { 
        deferred.resolve(response); 
        return deferred.promise; 
       } 
       deferred.reject('OptionsNotChanged'); 
       return deferred.promise; 

      }, function (response) { 
       $log.debug("UserService.changeOptions.error.status: " + response.status); 
       return $q.reject('OptionsNotChanged'); 
      }); 
      return promise; 
     }, 

Может someboddy сказать мне, почему мой объект в контроллере пуст после этого и как я могу добиться, чтобы просто получить манипулировали объект обратно из MasterDataService? Должен ли я делать это с обещанием и отсрочкой? И если да, как я могу манипулировать пользовательским объектом в службе, прежде чем возвращать его?

Заранее спасибо Sascha

+4

Не имеет смысла возвращать значения из асинхронной операции. Вы должны использовать обратные вызовы или обещания (на самом деле две версии того же самого). – Pointy

+0

Спасибо @Pointy. Дело в том, что я не знаю, как я могу манипулировать возвращенными данными в ecallback, прежде чем передавать его вызывающему снова асинхронным способом. – SLi

ответ

1

звучит, как вы хотите что-то вроде этого: (по существу $ ресурса)

angular.module('myApp',[])  
.factory('MasterDataService',function($http){ 
    var currentUser = {}; 
    return { 
     getCurrentUser: function(any,param,you,need){ 
      currentUser.$promise = $http({...}).then(function(response){ 
       var mainpulateUser = response.data; 
       //do business logic, 
       return angular.extend(currentUser,manipulatedUser);     
      }); 
      return currentUser; 
     } 
    };  
}) 
.controller('myCtrl',function(MasterDataService,$scope,$log){ 
    $scope.buttonTitle = 'UpdateUser'; 
    $scope.user = MasterDataService.getCurrentUser(); 
    $scope.user.$promise.then(function(user){ 
     $log.debug($scope.user === user); 
     $log.debug('current user -> ',$scope.user); 
    }); 
    $scope.getCurrentUser = function(){ 
     MasterDataService.getCurrentUser(); 
    } 
}); 

Вот является plunker. (Я использую $timeout, чтобы высмеять $http). Ключ должен поддерживать одну ссылку на вашего текущего пользователя.

Именно поэтому MasterService.getCurrentUser(); фактически обновляет пользователя. Все это всего лишь var currentUser = {}. Эта ссылка никогда не удаляется. следовательно, $scope.user === currentUser

В идеале, хотя вы не хотите выполнять бизнес-логику в службе поиска данных или вашем контроллере. Но ваша модель. Для того, чтобы определить модель вы можете сделать что-то вроде ...

angular.factory('User',function(){ 
    var User = function(initWith){ 
     initWith = initWith || {}; 
     this.firstName = initWith.firstName || '' 
     this.lastName = initWith.lastName || '' 
     this.position = 'employee' 
     this.lastRetrieved = new Date(); 

    } 
    User.prototype.doBusinessLogic = function(position){ 
     this.position = position; 
    } 
    return User; 
}); 

Вот раздвоенный plunk.

+0

Спасибо! Хорошо, дайте мне посмотреть, правильно ли я это понял. UserService, который вызывает вызовы в фоновом режиме, возвращает управляемый объект. Служба между ними имеет ссылочную переменную, которая заполняется методом обратного вызова с использованием метода угловой.extend() и его получение управляемого объекта в качестве параметра функции. Контроллер должен работать с $ prom и снова получать управляемый объект в функции обратного вызова.Я не понимаю, как работает функция getCurrentUser() в контроллере, просто позвонив в MasterDataService.getCurrentUser(). Инициализация выше имеет смысл для меня. – SLi

+0

Я не был достаточно точным. Пытались реализовать ваше предложение и просто видели, что мои «услуги» на самом деле «фабрики». Так что добавление ссылочной переменной невозможно ?! Кроме того, я не хочу вводить бизнес-логин в службу/фабрику, которая выполняет вызов в фоновом режиме. Могу ли я как-то поместить это в MasterDataService? В основном мой вопрос: что мне нужно сделать, чтобы вернуть манипулируемый объект из MasterDataService в контроллер? – SLi

+0

Я обновил свой ответ. Надеюсь, поможет! – calebboyd