我有一个简单的应用程序来显示客户列表,以及每个特定客户的详细信息页面。
基本上,有两个网址:
/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
});
}
});
到目前为止一切正常,但在模板中显示模型数据时我的问题就开始了。
有两种“方式”,哪一种是正确的?
选项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>
在这个例子中,我可以使用model.name
来渲染我的模型对象。那很好,直到我刷新页面!然后,model.name
返回的信息被删除。如果我尝试直接访问URL,也是一样的。我必须回到/clients
并再次点击该链接以查看我的客户名称。
然后我寻找另一种方式来显示我的数据,其中模型信息将在页面重新加载后继续存在。
选项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
来显示我的数据。它什么都不返回!
//app/templates/client.hbs
<h1>Client - {{model.name}}</h1> <-- model.name now returns nothing D:
然而,由于某种原因,使用循环DOES工作:
//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 实际上可以正常工作并返回数据,但是我必须使用循环来遍历单个记录,这不会让人觉得惯用/高效。
我非常困惑,任何澄清都会非常感激。
提前致谢!
答案 0 :(得分:1)
这是有趣的“神奇”事物之一,应该简化入门并使Ember看起来很容易 - 但实际上只是导致路由器最常见的用例最混乱。
至少它现在在指南中。
https://guides.emberjs.com/v2.12.0/routing/specifying-a-routes-model/#toc_dynamic-models
“注意:具有动态段的路径在通过URL输入时将始终调用其模型挂钩。如果通过转换输入路径(例如,使用链接到Handlebars帮助器时)和模型提供了context(link-to的第二个参数),然后不执行钩子。如果提供了一个标识符(例如id或slug),那么将执行模型钩子。“
所以,这是一件事......
但另一件事 - 是你回来了一个数组 - 因为你正在使用查询+过滤器 - 来创建一个数组的记录。
所以,如果你使用queryRecord() - 来获得1条记录 - 那么你就会得到你想要的东西。 :)
我只想补充说{{outlets}}
很酷。 Here's我通常如何做到 - 但是我可以看到我的路线总是以这种方式加载所有数据...... /我通常想要的 - 但可以看到在许多情况下如何 - 这是不可取的
而且 - 如果你遇到任何更严重的params问题......调查动态细分中的下划线 - 因为它可能会拖累你。