在{{#linkTo}}点击期间没有方法'addArrayObserver'

Lsd*_*lsd 2 ember.js

嘿不确定是否有人可以帮助我,但我一直在努力解决这个错误很长一段时间:

"Uncaught TypeError: Object <App.AssetType:ember408:2> has no method 'addArrayObserver'"

这是带有{{#linkTo}}单击时产生此错误的模板

<div class="row">
  <div class="twelve columns">
    <h2>{{title}} - Assets</h2>
  </div>
</div>
<div class="row">
  <div class="three columns">
    <ul>
      {{#each assetTypes}}
      {{#linkTo 'product.filter' this}}{{title}}{{/linkTo}}
      {{/each}}
    </ul>
  </div>
  <div class="nine columns">
    {{outlet}}
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

和应用程序代码

window.App = Ember.Application.create
  rootElement: '.solution_products_documents'

App.ApplicationRoute = Ember.Route.extend
  model: ->
    App.Product.find()
App.ApplicationController = Ember.ArrayController.extend
  sortProperties: ['title']

App.ProductRoute = Ember.Route.extend
  model: (params) ->
    App.Product.find params.product_id
  setupController: (controller, model) ->
    controller.set 'documents', model.get 'document_ids'

App.ProductController = Ember.ObjectController.extend
  assetTypes: (->
    docs = @get('documents')
    docs.getEach 'asset_type_id'
  ).property('documents')

App.ProductFilterRoute = Ember.Route.extend
  model: (params) ->
    type = App.AssetType.find params.asset_type_id
    product = this.modelFor 'product'
    docs = product.get 'document_ids'
    model = docs.filterProperty 'asset_type_id', type
App.ProductFilterController = Ember.ArrayController.extend()

App.Router.map ->
  @route 'index', { path: '/' }
  @resource 'product', { path: '/products/:product_id' }, ->
    @route 'filter', { path: '/filter-by/:asset_type_id' }

##
# MODELS / EMBER-DATA
##

serializer = DS.JSONSerializer.create()

serializer.configure 'App.Document',
  sideloadAs: 'documents'

serializer.configure 'App.AssetType',
  sideloadAs: 'asset_types'

serializer.configure 'App.Product',
  sideloadAs: 'products'

App.RestAdaptor = DS.RESTAdapter.extend
  serializer: serializer
  namespace: URL.slice 1
DS.Store.extend(
  adapter: App.RestAdaptor
  revision: 11
).create()

App.Product = DS.Model.extend
  title: DS.attr 'string'
  document_ids: DS.hasMany 'App.Document'

App.Document = DS.Model.extend
  title: DS.attr 'string'
  product_id: DS.belongsTo 'App.Product'
  asset_type_id: DS.belongsTo 'App.AssetType'

App.AssetType = DS.Model.extend
  title: DS.attr 'string'
  document_ids: DS.hasMany 'App.Document'

######### /> END MODELS #################
Run Code Online (Sandbox Code Playgroud)

如果我将URL #/products/4/filter-by/2放入地址栏,一切都按计划进行.只有当我点击{{#linkTo}}'s' 时才会收到此错误并且内容未显示.错误在它到达之前被抛出,App.ProductFilterRoute因为debugger路由中的语句没有被执行,但它在页面刷新时.

非常感谢任何帮助或方向,因为我真的不知道在哪里看.

更新:

如果我不使用{{#linkTo}}帮助程序而是手动构造URL

<a href="#/products/{{unbound controller.content.id}}/filter-by/{{unbound this.id}}">{{title}}</a>

一切正常.linkTo和manual href有什么不同?

mav*_*ein 6

当您导航到ProductFilterRoute时,该错误基本上表示Ember需要一个Array.

为什么Ember会在这里期待一个阵列?

  1. 您的Route 的控制器(ProductFilterController)是ArrayController类型.
  2. 我对coffeescript不太熟悉,但你的模型钩子似乎也返回了一个数组.重要提示:只有在通过URL输入您的应用程序时才会执行模型挂钩.(这就是为什么你的网址导航手册和HREF都工作从引用.EmberDoc:"一个钩子,你可以实现的URL转换成模型,这条路线")

为什么会抛出错误? 所以你的路线围绕着一个阵列.你只是传递一个普通的对象.因此,黄金法则是:将相同的数据结构(在本例中为数组)传递给您的{{linkTo}}助手,该助手由模型钩子实现返回.

可能的解决方案:

  1. 使用操作代替{{linkTo}}
  2. 在您的路线中实施一个动作,找到具有给定asset_type的所有文档并将其传递给您的路线.

对模板的修改:

<a {{action 'filterProductByAsset' this}}> {{title}} </a>
Run Code Online (Sandbox Code Playgroud)

ProductFilterRoute的扩展:

events:{
    filterProductByAsset : function(assetTypeId){
        type = App.AssetType.find(asset_type_id);
        product = this.modelFor('product');
        docs = product.get('document_ids');
        models = docs.filterProperty('asset_type_id', type);
        this.transitionTo("product.filter", models)
    }
}
Run Code Online (Sandbox Code Playgroud)