问题
应用程序必须具有可选的根前缀。前缀还有一个动态分段。
示例
的内容
/posts/1和/account/123/posts/1必须加载相同的路由和模板。
其中/account/123是前缀。123是前缀的动态段。
要求
- 所有url都必须是可访问的,无论是否带有前缀
-
加载前缀路由时,所有单页转换都必须在前缀url的上下文中。
/account/123/post/1到/account/23/post/2
-
当加载非前缀路由时,所有单页转换都必须在非前缀url的上下文中。
/post/1到/post/2
约束
- 现有的代码库具有没有前缀urls的路由
- 由于控制器、路由、临时已经存在,且不带前缀的路由中存在,因此解决方案必须重用现有代码
预期解决方案
-
所有进行spa转换的函数都必须查看window.location上下文并转换到前缀或非前缀路径。这将包括transitionTo、replaceWith、linkTo helper等功能
由于到助手的现有链接等,将路由名称设置为post.detail(非前缀路由(
-
必须对现有控制器、路由和模板进行最小的代码更改。
现有路线示例
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。
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一次(,但引擎本身也有一系列挑战。