【问题标题】:Ember routes - dynamic segments - wiring models togetherEmber 路由 - 动态段 - 将模型连接在一起
【发布时间】:2026-01-30 07:35:02
【问题描述】:

我想使用 ember 路由和模型来构建一些“雄心勃勃”的网络应用程序。 这就是我想要做的。我有一本书和作者模型。在显示作者资源列表时,如果用户单击作者,则通过嵌套路由显示该作者的所有书籍。因此,我想将作者 ID(或姓名)视为传递给图书模型的动态段。但似乎有一个限制,即dynamic segments 必须是当前模型的primaryKey,不能使用其他模型属性或模型。

我需要编写自定义反序列化器吗?如果是这样,适用于这种情况的示例小提琴将不胜感激。

这是一些示例代码,描述了我正在尝试做的事情,具体问题出现在 cmets 中。

Authors.hbs 模板

        <div class="span3">
            <h4>Books</h4>
            <ul class="unstyled">
                {{#each model}}
                    {{#linkTo 'authors.books' this}}<li>
                        {{name}} <small>{{date dob}}</small> <small> {{origin}}</small>
                    </li>{{/linkTo}}
                {{/each}}
            </ul>
        </div>
        <div class="span8">
            {{outlet}}
        </div>

初始化.coffee

@resource 'books', ->
  @resource 'book', {path: ':cube_id'}
@resource 'authors', ->
  @resource 'AUTHOR', {path: ':AUTHOR_id'}
  # QUESTION How to make the next line retrieve books-by-author from the book model?
  @route 'books', {path: '/books/:author_id'}

作者路线

module.exports = App.AuthorsRoute = Em.Route.extend
    model: ->
        App.Author.find()

预订路线

module.exports = App.BooksRoute = Em.Route.extend
    model: ->
        App.Book.find()
    # QUESTION How should the model be extended to allow for lookup by attribute?
    # model: (params) ->
    # App.Book.find { author: params.book_id }

作者模型

module.exports = App.Author = DS.Model.extend
    name: DS.attr 'string'
    origin: DS.attr 'string'
    dob: DS.attr 'date'

图书模型

module.exports = App.Book = DS.Model.extend
    name: DS.attr 'string'
    author: DS.attr # QUESTION How to wire together models here?
    #author: DS.belongsTo 'App.Author'
    publisher: DS.attr 'string'
    published: DS.attr 'date'

【问题讨论】:

    标签: ember.js ember-data


    【解决方案1】:

    前段时间我回答了一个有点相似的question(在guides 中也有描述)如何将模型与belongsTo 等关联链接起来(当模型记录属于 另一个模型)或hasMany(当一个模型记录有许多与其关联的另一个模型的记录时)以及如何在同一路径中使用多个模型。

    使用 Ember-Data 提供的关联,您可以在模型中创建属性,这些属性是 (a) 关联记录的集合或 (b) 作为相关记录父级的单个记录。然后在您的视图层中,只需按名称引用这些属性(集合或其他)(请参阅下面的建议模板)。

    对于您的特定应用,您可以按照以下建议编写模型:

    module.exports = App.Author = DS.Model.extend
        name: DS.attr 'string'
        origin: DS.attr 'string'
        dob: DS.attr 'date'
        books: DS.hasMany 'App.Book'
    
    module.exports = App.Book = DS.Model.extend
        name: DS.attr 'string'
        author: DS.belongsTo 'App.Author'
        publisher: DS.attr 'string'
        published: DS.attr 'date'
    

    请注意,现在两个模型相互了解。此模型声明将为您提供类似于以下表示的数据结构。所以每次有了Book的实例,就可以使用它的属性author来访问Author模型中定义的属性,比如dobname..等

    _____________________ ______________________ |作者 | |图书 | |----------------------| |-------------------------| (PK)| + id: int |◄-\ |--►►| + id: 整数 |(PK) | + 名称:字符串 | \ | | + 名称:字符串 | | + 来源:字符串 | \---Ԑ----| + 作者:App.Author |(FK) | + 出生日期:日期 | / | + 发布者:字符串 | (FK)| + 书籍:App.Book[] |-----/ | + 发表:日期 | |_____________________| |______________________|

    依靠您可以在视图层中引用 Author.books 的关联(在迭代作为控制器或模型属性的集合时,在视图中使用 content.books)来获取书籍集合由该作者使用,并将其与 {{#each}} 块一起使用。举个例子,看看这个fiddle,特别是在模板tags/tag中,我正在遍历与给定标签关联的帖子列表。尽管该示例适用于“博客”,但您当前使用的任何实体类型都可以使用相同的概念。

    因此,在您的情况下,即使在“authors.author”路线中,模板也可能如下所示:

    <h3>Books written by <em>{{name}}</em></h3>
    <ul>
        {{#each content.books}}
            <li>
               {{#linkTo books.book this}}
                   <i class="icon-book"></i> 
                   <!-- consider a helper to display the year or format the date
                        instead of "publisehd" which will display an ugly date -->
                   {{this.name}} (this.published) 
               {{/linkTo}}
            </li> 
        {{else}}
        <li>
            <div class="alert">
                <a class="close" data-dismiss="alert" href="#">&times;</a> 
                This author hasn't written any books that we know of.. seriously...
            </div>
        </li>
        {{/each}}
    </ul>
    

    请注意,{{#each}} 助手正在遍历集合,即 Book 模型的实例,可通过模型声明中的关联获得。

    【讨论】:

    • 感谢您的详尽回答。我的问题确实特别询问了嵌入式路由上下文中的动态段......你认为你可以添加一些关于它的 cmets 吗?
    • @ted.strauss 由于某种原因我没有看到这条评论。今天晚些时候我会看看它