在Ember.js中获取路径列表

4jb9z9bj  于 2023-01-13  发布在  其他
关注(0)|答案(3)|浏览(173)

在我的主页(index.hbs)上,我需要显示一个链接列表,指向每个符合给定条件的路由(例如,具有某个属性)。

// Define a route with some attribute
App.FirstRoute = Ember.Route.extend({
    showOnIndex: true
});

// Get a list of visible routes in the IndexController
visibleRoutes: function() {
    var routes = /* How to do this */
    return routes.filter(function(route) {
        route.get('showOnIndex'));
    });
}.property()

问题是如何获得routes。我发现可以通过以下方法获得路由名称列表:

var router = this.get('target');
var names = router.router.recognizer.names;

但是我找不到如何将它们转换成Route对象。大概Router有这样做的信息,但是AFAICS没有公开。有什么建议吗?

6rqinv9w

6rqinv9w1#

那么使用容器和查找呢?

Ember.keys(App.Router.router.recognizer.names).map(function(name) {
  return App.__container__.lookup('route:' + name);
}).compact();

我知道你访问的是私有的__container__,但是通常你不应该访问所有的路由。

uklbhaso

uklbhaso2#

这里有一种方法来做到这一点,虽然我认为这是有点可怕,甚至可能是危险的长期以来,因为它是使用Javascript的功能,而不是Ember API。我们开始通过您的'App'对象的路线。您可以得到它包含的所有类的列表使用对象。键(App)。然后你可以检查每一个,检查它是否是一个带有.superclass的路由,如果是路由,它将是Ember.Route。然后你可以检查每个原型的showOnIndex属性。

var allRoutes = [];
Object.keys(App).forEach(function(key, index, allKeys) {
    if (App[key].superclass === Ember.Route && App[key].prototype.showOnIndex === true) {
        allRoutes.push(App[key]);    
    }
});

现在我们有了一个包含showOnIndex为true的路由的所有类名的数组。
然而,你仍然有问题,从识别器的名称与路线的类名对齐,但由于Ember的方式是,像我的/url的路线将Map到MyUrlIndexRoute和'my.url.index'等,然后你可以拆分路线的大写,删除最后一部分('Route'),将它们连接在一起,并将其全部转换为小写。

var routesByName = [];
allRoutes.forEach(function(name, index, all) {
    var names = name.match(/[A-Z][a-z]+/g);
    names.pop();
    var routeName = names.join('.').toLowerCase();
    routesByName.push(routeName);
});

然后,您只需遍历模板中的routesByName,并为每个routesByName创建一个{{#link-to}}
我认为一个更好的方法来实现你想要的可能是保持一个Map的所有路线,其showOnIndex值分别在您的应用程序中,只是更新它的每一个新的你想添加的。它可能是更好的更安全的长期以来,因为谁知道如何ember内部将改变在未来可能会阻止做上述一些事情。
请注意,我在chrome的Ember应用程序中以调试器模式检查了所有这些,但没有直接运行所有的代码片段,因此对任何错误表示歉意。

mqkwyuun

mqkwyuun3#

在ember v4.9中,您可以在任何组件中执行以下操作:

export default class myComponent extends Component {
  @service router;

  @computed
  get routes() {
        // load RouterService 
        let router_service = this.router;

        // extract routes and format. 
        let routes = router_service._router._routerMicrolib.recognizer.names;
        let detailed_routes = Object.keys(routes)
                  .filter((key) => {
                          console.log(key === "error" )
                                return ! (key.match(/error/) || key.match(/loading/)
                                       || key.match(/index/) || key.match(/application/))
                  })
                  .map((route) => router_service.urlFor(route));

          console.log(detailed_routes);

        return detailed_routes
  }

}

相关问题