2017-06-08 52 views
1

我有一个Angular 1.5.9 Web应用程序和一个Node.js/Sails.js 0.12后端。 内部Angular运行UI路由器0.4来处理状态。将UI路由器状态解析为无角的URL

的状态定义可能是这样的(相当香草,我会说):

$stateProvider.state('dogs', { 
      url: '/ourdogsarecute_{specialIDofDog} 
     }). 
     state('dogs.specialDogState', { 
      url: '/specialinfo_{specialInfoOfDog}' 
     }); 

现在,以下情况发生:在后端(即角外),我要将诸如 {stateName: 'dogs.specialDogState', stateParams: {specialIDofDog: 11212, specialInfoOfDog: 'likesbones' } }的Angular UI路由器状态链接转换为有效的URL,如https://www.our-app.dog/ourdogsarecute_11212/specialinfo_likesbones

我不知道如何做到这一点,没有大量的手动工作。是否有一种用于UI路由器状态的解析器作为节点模块?

我可以以某种方式访问​​状态定义位于后端的前端代码。这不是问题。问题是从状态链接到URL的转换。

回答

1

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

在您的节点后台,添加UI路由器核心

npm install --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)); 
+0

谢谢!作品。但是,我猜你的意思是'npm install --save @ uirouter/core' 而不是'npm add --save @ uirouter/core'? – cis

+0

是的,我混杂了npm和纱线命令! –

0

仅供参考:我的解决方案现在看起来像这样。所有的 首先,我已经把我的状态定义成一个单独的文件,使其更容易从外部访问:

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

在后端,我创建了这个功能:

/** 
    * @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; 
    } 

的问题是:这可能会失败边缘的情况下,它必将对新功能的失败正在实施的UI状态路由器和这里建立了一个双向URL。所以,仍然希望能够直接使用UI路由器魔术的解决方案。