简体   繁体   中英

How to access and update resolve data of parent state inside onEnter method of child state of a ui router

So I have a ui-router state that looks like so:

Parent state

 $stateProvider

        .state('profile',{
            url: '/profile',
            views: {
                'contentFullRow': {
                    templateUrl: 'ng/templates/profile/partials/profile-heading-one.html',
                    controller: function($scope, profile,misc){
                        $scope.profile  = profile;
                        $scope.misc     = misc;
                    }
                },
                'contentLeft': {
                    templateUrl: 'ng/templates/profile/partials/profile-body-one.html',
                    controller: function($scope, profile,misc){
                        $scope.profile = profile;
                        $scope.misc     = misc;
                    }
                },
                'sidebarRight': {
                    templateUrl: 'ng/templates/profile/partials/todo-list-one.html',
                    controller: function($scope, profile,misc){
                        $scope.profile = profile;
                        $scope.misc     = misc;
                    }
                }
            },
            resolve: {
                profile: function($http){
                    return $http({method: 'GET', url: '/profile'})
                        .then (function (response) {
                        console.log(response.data)
                        return response.data;
                    });
                },
                misc: function($http){
                    return $http({method: 'GET', url: '/json/misc'})
                        .then (function (response) {
                        console.log(response.data)
                        return response.data;
                    });
                }
            }
        })

Child states

.state('profile.social', {
    url: '/social',
    controller:function($scope, profile, misc){
        $scope.profile = profile;
        $scope.misc = misc;
    },
    template: '<div ui-view></div>'
})
.state('profile.social.create',{
        url: '/create',
        onEnter: function($state){
          //Will call a modal here...
          //How do I access or update `$scope.profile` 
          //so far am doing this and it works 
          $state.$current.locals.globals.profile.first_name = 'My New name';
          //Is there any better way of doing this?
        }
})  

Question

Since $scope is not available in onEnter method, how do I access or update $scope.profile

So far am doing something like:

onEnter: function($state){
    $state.$current.locals.globals.profile.first_name = 'My New name';
}

This works but am wondering if there is a better way of doing this?

The correct thing to do is not try and access the controllers $scope from outside the controller. You should instead move your profile data to a service, and inject it into both the controller and the onEnter function (as needed). By separating profile data into a service, you can now access it from anywhere else too :)

For example:

.service('ProfileService', function(){
    var state = {};

    this.loadProfile = function(){
        return $http({method: 'GET', url: '/profile'})
            .then (function (response) {
                console.log(response.data);
                state.profile = response.data;
                return state.profile;
            });
    };

    this.getState = function(){
        return state;
    };
});

// the controller
controller: function($scope, ProfileService){
    $scope.state = ProfileService.getState();
}

// on enter
onEnter: function($state, ProfileService){
    var state = ProfileService.getState();
    state.profile.first_name = 'New Name';
}

I wrapped the profile data in a container ( state ), so that the profile key itself can be changed. So inside your view you will need to reference your profile like so: state.profile.first_name .

Also inside your resolve you will also need to inject the service, and run the load function returning the associated promise (so that resolve actually works).

Without knowing your requirements it is hard to describe the best way to do this, but in summary, you should pull your profile data into its own service, and inject it whenever you need it. The service should also encapsulate any promises that resolve once the service data has loaded.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM