Ember.js 渲染带有#链接到和动态段的模板

Ember.js 渲染带有#链接到和动态段的模板,ember.js,Ember.js,我有一个简单的应用程序来显示客户列表,以及每个特定客户的详细信息页面 因此,基本上有两个URL: /clients/ /clients/:slug/ 我在将我的客户端模型的结果呈现到模板中时遇到了一些问题,特别是在使用带有动态段的#指向辅助对象的链接时 我已经找到了两种方法,虽然我可以让它们都起作用,但我不知道哪一种是最好的,为什么 下面是我应用程序中的一些(简化)代码来解释 // app/models/client.js export default DS.Model.extend({ n

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

因此,基本上有两个URL:

/clients/

/clients/:slug/

我在将我的
客户端
模型的结果呈现到模板中时遇到了一些问题,特别是在使用带有动态段的
#指向
辅助对象的链接时

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

下面是我应用程序中的一些(简化)代码来解释

// 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
    });
  }
});
到目前为止,一切正常,但我的问题始于在模板中显示模型数据

有两种“方法”,哪一种是正确的

选项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}}
单击任何生成的链接将呈现客户端详细信息模板,
client.hbs

//app/templates/client.hbs
<h1>Client - {{model.name}}</h1>
但是。。。通过将
client.slug
而不是
client
作为参数传递给
#link to
,我无法再使用
model.name
显示数据。它什么也不返回

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

客户端-{model.name}}这是一个有趣的“魔法”东西,它被认为可以简化安装并使Ember看起来很简单,但实际上只是对路由器最常见的用例造成了最大的困惑

至少现在在指南里

“注意:通过URL输入带有动态段的路由时,其模型钩子将始终被调用。如果路由是通过转换输入的(例如,当使用“链接到把手”帮助程序时),并且提供了模型上下文(链接到的第二个参数),则钩子不会执行。如果标识符(如id或slug)则将执行模型挂钩。”

所以,这是一件事

但另一件事是,您正在返回一个数组,因为您正在使用query+filter创建一个记录数组

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

我要补充的是,
{{outlets}}
很酷。我通常是怎么做的-但我可以看到我的路由总是以这种方式加载所有数据…/这通常是我想要的,但在很多情况下,我可以看出这是不可取的


而且-如果你遇到任何更古怪的参数问题。。。调查动态段中的下划线-因为它可能会拖累您。

选项B是正确的,通过只传递slug,您可以在转换到路由或直接转到路由(通过刷新或立即转到链接)时查询您的模型。恢复状态所需的所有内容都存储在URL中。我猜您的后端在执行store.query时会返回一个数组(可能只有一个结果)。这可能就是为什么您的client.hbs要求您在实际上是一个数组的模型上循环。@pjcarly感谢您的回复!您知道有没有一种方法可以直接在Ember中访问数组,而不必使用循环?类似于{model.client.name}?有
model.firstObject
model.lastObject
属性请注意firstObject和lastObject,这仅适用于Ember.Array或应用程序的构建。我建议在模型钩子中处理它,而不是在模板中处理它。查询({}).then((results)=>{返回结果[0];});如果您可以控制API,我强烈建议让
/clients/:slug/
端点返回单个记录,而不是单个元素数组。然后,您将使用
store.queryRecord
来获取单个客户机,而不是
store.query({filter…)
。这应该会让事情变得更干净。@pjcarly@sheriffderek它成功了!!queryRecord成功了!所以是的,我可以确认我的错误是使用
store.query
,这意味着返回一个项目数组,而不是返回单个对象的
store.queryRecord
。现在我可以使用
{model.name}
在我的模板中,它可以工作,是的。我要说,在你弄清楚路由器转换以及它实际调用模型挂钩的方式和时间之前,你并不真正理解Ember。我仍然在弄清楚:)再次感谢你的帮助!
//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}}