将路径/ URL匹配到ui-router中的状态

时间:2015-08-04 17:25:13

标签: angularjs angular-ui-router

我有一个字符串路径,由$ state.href()在我的代码中的其他地方生成。我想使用该变量来查找匹配该路径的$ state对象(我假设这是ui-router在内部做的,以决定转换到哪个状态)。

4 个答案:

答案 0 :(得分:1)

这应该可以解决问题。它返回给定任何URL的状态。您必须首先提取URL的角度路径部分。即#符号之后的东西。您还必须注入$ state和$ urlMatcherFactory。

   var _urlMatcherForStateMaps = [];

  /**
   * Iterate through all states available in the app and return the first state that matches the specified url.
   * The URL matchers for the states are cached to not have to generate the RegExs outside of the first time this
   * app is called.  I don't think app states can change at runtime, but if I'm wrong about that the cache will
   * have to be cleared.
   * @param urlPath The relative angular url path to match.  This will not work with absolute urls.  You want to send 
   *                the path after the # i.e. 
   *                '/path/id' not 'http://host/#/path/id'
   * @returns {*} The state or undefined if one is not matched
   * @private
   */
    function _findStateForUrl(urlPath){

        //Build a cache of url matches for quicker access
        if (!_urlMatcherForStateMaps.length) {
            //Get a list of all available states in the order they are defined in app.js
            var stateList = $state.get();
            for (var i = 0; i < stateList.length; i++) {
                var state = stateList[i];
                var urlMatcherForState = $urlMatcherFactory.compile(state.url);
                _urlMatcherForStateMaps.push({
                    matcher: urlMatcherForState,
                    state: state
                });
            }
        }

        //Iterate through our url matches and return the first one that matches
        for (i = 0; i < _urlMatcherForStateMaps.length; i++) {
            var urlMatcherObject = _urlMatcherForStateMaps[i];
            var matches = urlMatcherObject.matcher.exec(urlPath);
            if (matches) {
                return urlMatcherObject.state;
            }
        }
    }

答案 1 :(得分:0)

您可以访问$state.$current(而不是$ state.current)。特别是它的属性.parent允许您遍历树并找到顶部(抽象)状态。请注意,此树中的顶级状态(使用parent==null)是系统状态__inactives,而不是用户定义的。

此外,您将使用.$current.url.prefix来匹配无参数状态的URL。但是,对于具有参数

的状态的URL匹配,这将是一个更复杂的问题

答案 2 :(得分:0)

你可以这样做:

将此添加到您的配置

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

然后在以下任何地方执行此操作:

var state_regexp = $state.get(state_name).$$state().url.regexp;
if(state_regexp.test($location.$$path)){
   //Yeah matched
}

注意:记得注入$ state和$ location

答案 3 :(得分:-2)

来自the wiki

  

激活州有三种主要方式:

     
      
  1. 调用$ state.go()。高级便利方法。 Learn More
  2.   
  3. 单击包含ui-sref指令的链接。 Learn More
  4.   
  5. 导航到与州关联的网址。 Learn More
  6.   

您似乎正在尝试使用您拥有的$state.href()变量转换到某个州。如果是这样,而不是使用从$state.href()获得的网址,您可能最好使用$state.go()直接导航到州本身。

如果你真的想对这个状态对象本身做些什么,我建议你听$stateChangeStart。这是一个例子:

app.run(function($rootScope) {
  $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
    if (fromState.name === 'foo') {
      // do something with toState
      // toState === { name: 'bar', templateUrl: '/bar', controller...}
    }
  });
});