ANGULAR-UI-ROUTER: Resolve state from URL

前端 未结 4 1297
清酒与你
清酒与你 2020-12-16 20:14

I\'m making an app with dynamical states, and sometimes I need to resolve the state name from the url.

e.g.: I have /dashboard/user/12268 and I need to

相关标签:
4条回答
  • 2020-12-16 20:36

    The current state can be obtained from $state service. like $state.current Check this api http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$state

    0 讨论(0)
  • 2020-12-16 20:55

    To get @Chris T solution to work for me I am doing this inside a Service:

    app.service('Helper', ['$state', '$location',
        function($state, $location){
    
           var services = {};
    
           services.stateIs = function(state_name){
              var current_path = $location.$$path;
              var state = $state.get(state_name);
    
              if(state){
                  var state_regexp = state.$$state().url.regexp;
                  return state_regexp.test(current_path);
              }else{
                  return false;
              }
           }
    
           return services;
        }
    ]);
    

    So later I can inject Helper anywhere and do this:

    if(Helper.stateIs('app.user')){
        //yeah 
    }
    
    0 讨论(0)
  • 2020-12-16 20:58

    Finally I've had to make a small modification on ui-router's $state service to get to the solution.

    It results that the states stored in the service have more information that the one given on the $state.get() method. So I iterated over them to get a state that matches with my URL:

    /**
     * @ngdoc function
     * @name ui.router.state.$state#fromUrl
     * @methodOf ui.router.state.$state
     * 
     * @description
     * A method to resolve a state and its parameters from a given URL
     *
     * @returns {boolean} Returns a state that matches with the given URL, or undefined if no match
     */
    $state.fromUrl = function(url) {
      if(!angular.isString(url)) {
        //Only valid strings allowed
        return undefined;
      }
      
      
      var keys = objectKeys(states);
      //Iterate over all states
      for(var i = 0; i < keys.length; i++) {
        var state = states[keys[i]];
        var stateArgs = state.url.exec(url);
    
        //If the state's URL does not match then stateArgs will be false
        if(!!stateArgs) {
          return {
            name: state.name,
            args: stateArgs
          }
        }
      }
    
      return undefined;
    };

    Regards,
    Alx

    0 讨论(0)
  • 2020-12-16 21:01

    https://github.com/angular-ui/ui-router/issues/1651

    You can expose the internal state implementation by using the .decorator hook on $stateProvider. You can decorate any property of the state builder; I chose 'parent' arbitrarily.


    app.config(function($stateProvider) { 
      $stateProvider.decorator('parent', function (internalStateObj, parentFn) {
         // This fn is called by StateBuilder each time a state is registered
    
         // The first arg is the internal state. Capture it and add an accessor to public state object.
         internalStateObj.self.$$state = function() { return internalStateObj; };
    
         // pass through to default .parent() function
         return parentFn(internalStateObj); 
      });
    });
    

    Now you can access the internal state object using .$$state(), e.g.

    var publicState = $state.get("foo");
    var privateInternalState = publicState.$$state();
    

    Second, loop over each state in $state.get() and test them against your URL fragment.

    angular.forEach($state.get(), function(state) { 
      var privatePortion = state.$$state();
      var match = privatePortion.url.exec(url, queryParams);
      if (match) console.log("Matched state: " + state.name + " and parameters: " + match);
    });
    
    0 讨论(0)
提交回复
热议问题