使用#link-to 和动态片段呈现模板

rendering templates with #link-to and dynamic segments

我有一个简单的应用程序来显示客户列表,以及每个特定客户的详细信息页面。

所以基本上,两个 URLs:

/clients/
/clients/:slug/

我在将 Client 模型的结果渲染到模板中时遇到了一些问题,特别是在将 #link-to 助手与动态细分一起使用时。

我找到了两种方法,虽然我可以让它们都起作用,但我不知道哪一种最好,为什么。

这里是我的应用程序中的一些(简化的)代码来解释。

// app/models/client.js
export default DS.Model.extend({
  name: DS.attr('string'),
  slug: DS.attr('string')
});

(我的实际模型更大,但这些是唯一相关的字段)

这是我的路线:

// app/router.js
Router.map(function() {
  this.route('clients');
  this.route('client', { path: 'clients/:slug' });
});

注意:我没有嵌套路由,因为我不想使用 {{outlet}} 嵌套模板功能。

这是客户的路线,我在其中检索我的客户列表

// app/routes/clients.js
export default Route.extend({
  model: function() {
    return this.get('store').findAll('client'); // fetch all Clients
  }
});

最后,这是获取单个客户端信息的路径:

// app/routes/client.js
export default Route.extend({
  model: function(params) {
    return this.store.query('client',  {
      filter: { slug: params.slug } // fetch one specific client, by slug
    });
  }
});

到目前为止一切正常,但我的问题是在模板中显示模型数据时出现的。

有两个"ways",哪个是正确的??

选项 A:

//app/templates/clients.hbs
// list all clients using #each
{{#each model as |client|}}
  {{#link-to "client" client}} // pass the "client" object to generate my dynamic routes
    {{client.name}}
  {{/link-to}}
{{/each}}

单击任何生成的 link 将呈现客户详细信息模板,client.hbs

//app/templates/client.hbs
<h1>Client - {{model.name}}</h1>

在这个例子中,我可以使用 model.name 来渲染我的模型对象。很好,直到我刷新页面!然后 model.name 返回的信息被删除。如果我尝试直接访问 URL 也是一样。我必须返回 /clients 并再次单击 link 以查看我客户的姓名。

然后我寻找另一种方式来显示我的数据,其中模型信息可以在页面重新加载后继续存在。

选项 B:

经过大量阅读,我发现了使用特定客户端 slug/id 作为 #link-to

的参数的建议
// app/templates/clients.hbs
// list all clients using #each
{{#each model as |client|}}
  {{#link-to "client" client.slug}} // specifically use the actual slug/id, and not the object
    {{client.name}}
  {{/link-to}}
{{/each}}

但是...通过将 client.slug 而不是 client 作为参数传递给 #link-to,我无法再使用 model.name 来显示我的数据。简直returns没什么!

//app/templates/client.hbs
<h1>Client - {{model.name}}</h1> <-- model.name now returns nothing D:

但是,出于某种原因,使用循环确实有效:

//app/templates/client.hbs
{{#each model as |client|}}
  <h1>Client - {{client.name}}</h1> <-- using loop even though I only have one record :(
{{/each}}

因此选项 B 有效,并且在重新加载页面或从 URL 直接访问后正确显示信息。

但我现在正在使用循环来显示单个记录!而且我找不到实际可行的替代解决方案。

总结一下:

选项 A 感觉是正确的方法,但重新加载页面会清除数据。

选项 B 实际上有效并且 returns 数据,但我必须使用循环遍历单个记录,这感觉不惯用 / 高效.

我非常困惑,任何澄清将不胜感激。

提前致谢!

这是有趣的 'magic' 事情之一,应该可以简化入职流程并使 Ember 看起来很容易 - 但实际上只是对最常见的内容造成了最大的困惑 use-case 用于路由器。

至少它现在在指南中。

https://guides.emberjs.com/v2.12.0/routing/specifying-a-routes-model/#toc_dynamic-models

"Note: A route with a dynamic segment will always have its model hook called when it is entered via the URL. If the route is entered through a transition (e.g. when using the link-to Handlebars helper), and a model context is provided (second argument to link-to), then the hook is not executed. If an identifier (such as an id or slug) is provided instead then the model hook will be executed."

所以,这是一回事...

但另一件事 - 是你正在取回一个数组 - 因为你正在使用查询 + 过滤器 - 创建一个记录数组

因此,如果您使用 queryRecord() - 这意味着获得 1 条记录 - 那么您将得到您想要的。 :)

我只想补充一点 {{outlets}} 很酷。 Here's 我通常是怎么做的 - 但我可以看到我的路线总是以这种方式加载所有数据....../我通常想要的 - 但在很多情况下可以看到 - 它不会被期望.

而且 - 如果您 运行 遇到任何更古怪的参数问题...调查动态部分中的下划线 - 因为它可能在欺骗您。