在成员路由中具有可选前缀的



问题

应用程序必须具有可选的根前缀。前缀还有一个动态分段。

示例

的内容

/posts/1和/account/123/posts/1必须加载相同的路由和模板。

其中/account/123是前缀。123是前缀的动态段。

要求

  1. 所有url都必须是可访问的,无论是否带有前缀
  2. 加载前缀路由时,所有单页转换都必须在前缀url的上下文中。

    /account/123/post/1到/account/23/post/2

  3. 当加载非前缀路由时,所有单页转换都必须在非前缀url的上下文中。

    /post/1到/post/2

约束

  1. 现有的代码库具有没有前缀urls的路由
  2. 由于控制器、路由、临时已经存在,且不带前缀的路由中存在,因此解决方案必须重用现有代码

预期解决方案

  1. 所有进行spa转换的函数都必须查看window.location上下文并转换到前缀或非前缀路径。这将包括transitionTo、replaceWith、linkTo helper等功能

    由于到助手的现有链接等,将路由名称设置为post.detail(非前缀路由(

  2. 必须对现有控制器、路由和模板进行最小的代码更改。

现有路线示例

NewRouter.map(function() {
this.route('posts', function() {
this.route('detail',{path: "/:id"});
this.route('comments', function() {
this.route('detail',{path: "/:id"});
});
});
});

控制器、路由、模板已经存在,用于post、post.detail、comments、comment.detail。

Ember路由器具有属性rootURL。如果你想从http://emberjs.com/blog/,则有必要指定/blog/的根URL。

这可以通过在ENV:上配置rootURL属性来实现

module.exports = function(environment) {
var ENV = {
modulePrefix: 'my-blog',
environment: environment,
rootURL: '/blog/',
locationType: 'auto',
};
}

不过,在您的情况下,这个rootURL是动态的。EmberRouter有一个init函数,您可以使用它在运行时动态设置这个值,然后通过动态检查加载的URL来构建应用程序中的任何URL。

export default class Router extends EmberRouter {
init(){
super.init(...arguments);
// trailing slash is required for rootURL
let acctsSubUrl = window.location.pathname.match(/^/accounts/d+//);
if(acctsSubUrl){
this.rootURL = acctsSubUrl[0];
}
}
location = config.locationType;
rootURL = config.rootURL;
}

如果执行此操作,则将rootURL的默认ENV值设为/。这将解决您对动态前缀的需求,该前缀在存在时加载所有路由URL。我针对Ember 3.17测试了这个,它可以

我不知道是否有正确的答案。我在这里看到了几个选项,但在采取这些选项之前,要非常确定你确实需要URL中的帐户信息,而且它不能只存储在服务中。

我认为最好的选择是只在两个地方创建路线,然后复制所需的组件树。你会有一些代码重复,这可能是一个可以为减少担心而付出的代价。

//posts/detail/index.hbs
`<PostDetail @id={{@model.id}} @accountId={{null}} />
//account/posts/detail/index.hbs
`<PostDetail @id={{@model.id}} @accountId={{@model.account}} />

您也可以尝试使用引擎并两次装载相同的路由(每个URL一次(,但引擎本身也有一系列挑战。

最新更新