Ember 使用 renderTemplate 和 setupController 进行路由

Ember Routing with renderTemplate and setupController

我正在构建一个 Ember 应用程序来展示一个简单的类似 Twitter 的标记系统。当用户访问 /items 时,他或她将看到所有 items 的列表。当用户访问 /tags 时,用户将看到 tags 的列表作为链接。当用户单击这些链接之一时,用户 应该 被定向到 /tags/:id 并且将看到所有 items 标记有特定 tag。然后用户将能够 search/sort/manipulate 项目,因为 he/she 将能够从 ItemsRoute.

如何使 TagRoute 使用 ItemsController 并呈现 items 模板,使用标签的关联 items 作为模型?

我在 TagRoute 中尝试了不同的钩子组合,但我找不到有效的方法。我这边似乎存在根本性的误解。

这是我的相关代码:

router.js.coffee

App.Router.map ()->
  @resource 'items'
  @resource 'tags', ->
    @resource 'tag', path: ':tag_id'

routes/tag.js.coffee

App.TagRoute = Ember.Route.extend
  model: (params)->
    @get('store').find 'tag', params.tag_id
  controllerName: 'items'
  setupController: (controller, model)->
    @controllerFor('items').set('model', model.items)
  renderTemplate: ->
    @render 'items', ->
      into: 'tags'
      controller: 'items'

templates/tags.hbs

<ul class="tag-list">
  {{#each tag in model}}
  <li>
    {{#link-to 'tag' tag}}
      {{tag.name}}
    {{/link-to}}
  </li>
  {{/each}}
</ul>

{{outlet}}

models/items.js.coffee

App.Item = DS.Model.extend(
  body:       DS.attr('string')
  checked:    DS.attr('boolean')
  tags:       DS.hasMany('tag')
)

models/tags.js.coffee

App.Tag = DS.Model.extend(
  name:             DS.attr('string')
  taggings_count:   DS.attr('number')
  items:            DS.hasMany('item')
)

目前,这给我一个错误:

Error while processing route: tag Cannot assign to read only property 'name' of function () {
        return {
          into: 'tags',
          controller: 'items'
        };
      } TypeError: Cannot assign to read only property 'name' of function () {
        return {
          into: 'tags',
          controller: 'items'
        };
      }

查看 Chrome 中的 Ember 路由检查器,controllerName 属性 是唯一覆盖 Ember 默认值的路由检查器,并且 Ember 仍然尝试渲染生成的 tag 模板。

正如 ahmed.hoban 所建议的,我已经使用查询参数解决了这个问题。这有助于我避免重复路由和使用纠结的路由器。它会访问数据库,这不是可取的,但我现在不确定我是否会将其作为一项要求。我可以控制全栈,所以我可以对后端进行调整以支持请求。

router.js.coffee

App.Router.map ()->
  @resource 'tags', path: '/', ->
    @resource 'items'

routes/tag.js.coffee - 已删除

templates/tags.hbs

<ul class="tag-list">
  {{#each tag in model}}
  <li>
    {{#link-to 'items' (query-params tag=tag.id)}}
      {{tag.name}}
    {{/link-to}}
  </li>
  {{/each}}
</ul>

{{outlet}}

controllers/items.js.coffee

App.ItemsController = Ember.ArrayController.extend(
  needs: 'tags'

  queryParams: ['tag']
  tag: null

  items: (->
    tag = @get 'tag'
    if tag
      @store.find 'item', tag: tag
    else
      @get 'model'
  ).property('tag', 'model')
)