Angular ui-router中的双向子/资源关系

Bidirectional sub/resource relationships in Angular ui-router

本文关键字:资源 关系 ui-router Angular      更新时间:2023-09-26

我可以对Jax-RS中的资源类做一件很有意思的事:

@Path("/clubs")
class ClubsResource {
      @Path("/")
      @GET
      public Response getClubs() {
          // return list of clubs
      }
      @Path("/{id}")
      @GET
      public Response getClub(@PathParam("id") long id) {
          // return club with given id 
      }
     //lots of other club endpoints
}
@Path("/people")
class PeopleResource {
      @Path("/")
      @GET
      public Response getPeople() {
          // return list of people
      }
      @Path("/{id}")
      @GET
      public Response getPerson(@PathParam("id") long id) {
          // return person with id 
      }
       //THIS IS THE NIFTY PART         
      @Path("/{id}/clubs")
      public ClubsResource getClubStuffForPerson(@PathParam("id") long personId) {
          return new ClubsResource(personId);
      }
}

它的妙处在于它允许我用ClubsResource"扩展"PeopleResource -它给了我端点/people/1234/clubs, /people/1234/clubs/5678people/1234/clubs/<every other ClubsResource endpoint>,几乎是免费的。

我想在我的angular应用中使用ui-router做类似的事情。

所以我有:

$stateProvider
     .state('people', { 
          url: '/people'
      }).state('people.detail', { 
          url: '/{personId}' 
       //lots of other people states 
      }).state('clubs', { 
          url: '/clubs'
      }).state('clubs.detail', { 
          url: '/{clubId}'
      }).state('clubs.detail.edit', { 
          url: '/edit'
      })
      // lots of other clubs states

我想用所有clubs.*状态"扩展"people.detail状态(反之亦然):例如,我想要一个people.detail.clubs状态(在url /people/1234/clubs),显示我1234人的所有俱乐部。/clubs/5678/peopleclubs.detail.people状态显示了5678俱乐部的所有人。

显然,我可以手动创建这些状态,但我想知道是否存在类似于Jax-RS中的子资源定位器的ui-router结构,允许我做我在那里做的事情(因为这将是更容易维护的给定"俱乐部"answers"人"的任意复杂性状态)。

更新:作为实现此的一种粗糙且不完整的方式,我正在做:

//people_states.js 
var list = {/* object-style definition of people list state */  };
var detail = {/* object-style definition of people detail state */  };
module.constant('PeopleStates', {
    list: function(customUrl){
        //param allows other states to use same definition with different URL
        var toReturn = angular.copy(list);
        toReturn.url = customUrl ? customUrl : toReturn.url; 
        return toReturn;
     }
    detail: function(url){/* same idea */ }
}

 //club_states.js 
 //var list, detail... same idea 
 module.constant('ClubStates', {/*same idea*/})
 module.config(function($stateProvider, PeopleStates, ClubStates){ 
      $stateProvider
          .state('clubs', ClubStates.list()) 
          .state('clubs.detail', ClubStates.detail()) 
          .state('clubs.detail.members', PeopleStates.list("/members"))                
          .state('clubs.detail.members.detail', PeopleStates.detail()) 
           //^^ so URL is /clubs/5678/members/1234             
 }) 

这帮助我消除了大部分的代码重复,但感觉很黑客,并没有触及我问题的核心——ui-router是否提供了一种更优雅的方式来实现这一点。

据我所知,ui-router开箱外不支持这一点,所有.state()状态都必须声明为在ui-router中注册。所支持的是状态是嵌套的,并且在进入子状态之前必须解析所有先前的状态。

我也遇到过类似的问题,在多个状态下重复解析函数,我通过将其抽象为一个服务来解决,就像你正在做的那样。

在其他项目中,我还做了一个基于一些参数生成完整状态声明(名称,url,模板,ctrl, resolve)的函数,因为我打开了更像是20个稍微不同的模态作为状态:)

所以最后你抽象出状态定义的生成这没问题