Javascript 将UI路由器状态解析为URL而不使用

Javascript 将UI路由器状态解析为URL而不使用,javascript,angularjs,node.js,angular-ui-router,Javascript,Angularjs,Node.js,Angular Ui Router,我有一个Angular 1.5.9 web应用程序和一个Node.js/Sails.js 0.12后端。 内部运行UI路由器0.4以处理状态 州的定义可能是这样的(我认为相当普通): 现在,出现了以下情况:在后端(即角度外部),我必须转换角度UI路由器状态链接,如 {stateName:'dogs.specialDogState',stateParams:{specialIDofDog:11212,specialIfoofDog:'likesbones'}}转换为有效的URL,如https://

我有一个Angular 1.5.9 web应用程序和一个Node.js/Sails.js 0.12后端。 内部运行UI路由器0.4以处理状态

州的定义可能是这样的(我认为相当普通):

现在,出现了以下情况:在后端(即角度外部),我必须转换角度UI路由器状态链接,如
{stateName:'dogs.specialDogState',stateParams:{specialIDofDog:11212,specialIfoofDog:'likesbones'}}
转换为有效的URL,如
https://www.our-app.dog/ourdogsarecute_11212/specialinfo_likesbones

如果没有大量的手工工作,我不知道怎么做。是否有一种将UI路由器状态作为节点模块的解析器


我可以从后端访问状态定义所在的前端代码。这不是问题所在。问题是从状态链接到URL的转换。

供参考:我的解决方案现在看起来像这样。 首先,我将我的状态定义放在一个单独的文件中,以便从外部访问它:

var myStates = [
    {
        name: 'dogs', stateProperties: {
        url: '/ourdogsarecute_{specialIDofDog}'
    }
    }, {
        name: 'dogs.specialDogState', stateProperties: {
            url: '/specialinfo_{specialInfoOfDog}'
        }
    }];
然后在我的app.config中

for(var i = 0; i < myStates.length; i++) {
            $stateProvider.state(myStates[i].name, myStates[i].stateProperties);
        }
for(var i=0;i
在后端,我创建了以下函数:

/**
   * @description Turns state name and state params into a URL string, using stateLinks definition synchronized from front end (being UI router state definitions)
   * @param {string}  stateName Something like 'dogs.info.specialAttributes'
   * @param {object}  stateParams Something like {dogID: 34346346, dogStatus: 'private', dogInfo: 'food'}
   * @returns {string} URL
   */
  stateLinkResolve: function(stateName, stateParams) {

    if(!(stateName && stateName.length > 0)) {
      return '/';
    }

    var resultUrl = '';

    var splittedSubStates = stateName.split('.');// split "dogs.info.specialAttributes" into ["dogs","info","specialAttributes"]

    var currentStateInHierarchy = '';
    for(var i = 0; i < splittedSubStates.length; i++) {

      /* Add dot if "in between": not the first, not the last. So that "dogs" remains "dogs", but when going to "dogs.info", we want the dot in between */
      if(i > 0 && i < (splittedSubStates.length + 1) ) {
        currentStateInHierarchy += '.';
      }
      currentStateInHierarchy += splittedSubStates[i]; // Add current splitted name (being only the last name part) to the state name in its context. I.e. when doing "info", we want to access "dogs.info"
      var currState = _.find(stateDefs,{name: currentStateInHierarchy});
      var urlRaw = currState.stateProperties.url;

      /* uiRouter URLs may contain wildcards for parameter values like /ourdogs_{dogID:int}_{dogStatus}/:dogInfo.
        We go through each of these three types and replace them with their actual content.
          */
      for(var currentParam in stateParams) {
        urlRaw = urlRaw.replace(':' + currentParam, stateParams[currentParam]); // search for ":paramName" in URL
        urlRaw = urlRaw.replace('{' + currentParam + '}', stateParams[currentParam]); // search for "{paramName}" in URL

        // search for "{paramName:paramType}" in URL
        var uiRouterParamTypes = ["hash", "string", "query", "path", "int", "bool", "date", "json", "any"];
        for(var j = 0; j < uiRouterParamTypes.length; j++) {
          urlRaw = urlRaw.replace('{' + currentParam + ':' + uiRouterParamTypes[j] + '}', stateParams[currentParam]);
        }
      }
      resultUrl += urlRaw;
    }
    return resultUrl;
  }
/**
*@description使用从前端同步的StateLink定义(即UI路由器状态定义),将状态名称和状态参数转换为URL字符串
*@param{string}stateName类似于“dogs.info.specialAttributes”
*@param{object}stateparms类似于{dogID:34346346,dogStatus:'private',doginfood:'food'}
*@returns{string}URL
*/
stateLinkResolve:函数(stateName、stateParams){
如果(!(stateName&&stateName.length>0)){
返回“/”;
}
var resultur='';
var splittedSubStates=stateName.split('.');//将“dogs.info.specialAttributes”拆分为[“dogs”、“info”、“specialAttributes”]
var currentStateInHierarchy='';
对于(var i=0;i0&&i<(splittedSubStates.length+1)){
currentStateInHierarchy+='.';
}
currentStateInHierarchy+=splittedSubStates[i];//将当前拆分的名称(仅为姓氏部分)添加到其上下文中的州名称中。即,在执行“info”时,我们希望访问“dogs.info”
var currState=u2;.find(stateDefs,{name:currentStateInHierarchy});
var urlRaw=currState.stateProperties.url;
/*uiRouter URL可能包含参数值的通配符,如/ourdogs{dogID:int}{dogStatus}/:dogInfo。
我们将逐一介绍这三种类型,并用它们的实际内容替换它们。
*/
for(stateParams中的var currentparm){
urlRaw=urlRaw.replace(':'+currentparm,stateparms[currentparm]);//在URL中搜索“:paramName”
urlRaw=urlRaw.replace('{'+currentParam+'}',stateParams[currentParam]);//在URL中搜索“{paramName}”
//在URL中搜索“{paramName:paramType}”
var uiRouterParamTypes=[“哈希”、“字符串”、“查询”、“路径”、“int”、“bool”、“日期”、“json”、“任意”];
对于(var j=0;j

问题是:在边缘情况下,这可能会失败,而在UI状态路由器上实现的新功能以及在那里构建URL的方式上,这肯定会失败。因此,仍然希望找到一种直接使用UI路由器魔术的解决方案。

UI路由器1.0将代码分为UI路由器核心和UI路由器angularjs。您可以在节点后端使用ui路由器核心(没有外部依赖项)来生成这些URL。由于您已经将状态作为JSON文件提供,您只需在后端的ui router core中注册状态,然后使用状态对象生成URL

在节点后端,添加ui路由器核心

npm安装——保存@uirouter/core

// The library exports most of its code
var UIR = require('@uirouter/core');

// Create the router instance
var router = new UIR.UIRouter();
// Get the state registry
var registry = router.stateRegistry;

var states = [
  { name: 'dogs', url: '/ourdogsarecute_{specialIDofDog}' },
  { name: 'dogs.specialDogState', url: '/specialinfo_{specialInfoOfDog}' },
];

states.forEach(state => registry.register(state));

var params = { specialIDofDog: '11212', specialInfoOfDog: 'lovesbones' };

// Get the internal state object
var stateObj = registry.get('dogs.specialDogState').$$state();
// Generate the URL
console.log(stateObj.url.format(params));

谢谢作品然而,我猜,你的意思是
npm安装--save@uirouter/core
而不是
npm添加--save@uirouter/core
// The library exports most of its code
var UIR = require('@uirouter/core');

// Create the router instance
var router = new UIR.UIRouter();
// Get the state registry
var registry = router.stateRegistry;

var states = [
  { name: 'dogs', url: '/ourdogsarecute_{specialIDofDog}' },
  { name: 'dogs.specialDogState', url: '/specialinfo_{specialInfoOfDog}' },
];

states.forEach(state => registry.register(state));

var params = { specialIDofDog: '11212', specialInfoOfDog: 'lovesbones' };

// Get the internal state object
var stateObj = registry.get('dogs.specialDogState').$$state();
// Generate the URL
console.log(stateObj.url.format(params));