質問

My goal is to show a username, which needs to manipulated on a web page. The mnaipulation should be done centrally in a service (MasterDataService). I want to used a scope variable on the screen which is defined in a controller. The controller is calling a centralize service. The service is calling another service which is calling the back-end, processing the user name and returning the result back to the controller. The result should just be the JSON object and not the resolved request (defer and promise).

Web Page -> page controller-> centralized service-> user service -> and the way back

I am doing it like this

Web Page

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

Controller

$scope.getCurrentUser = function () {

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

MasterDataService

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

Can someboddy tell me why my object in the controller is empty afterwards and how I can achieve to just get the manipulated object back from the MasterDataService? Do I have to do it with promise and defer as well? And if so, how can I manipulate the user object in the service before returning it?

Thanks in advance Sascha

役に立ちましたか?

解決

Sounds like you want something like this: (essentially $resource)

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

Here is a plunker. (I use $timeout to mock $http) The key is to maintain one reference to your current user.

That is why MasterService.getCurrentUser(); actually updates the user. Its all just var currentUser = {}. That reference never gets removed. hence $scope.user === currentUser

Ideally though You don't want to do business logic in your data-retrieval service or your controller. But your model. To define a model you might do something like...

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

Here is a forked plunk.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top