2

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

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

这是带有 's 的模板,{{#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>

和应用程序代码

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 #################

如果我将 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 和手动 href 有什么不同?

4

2 回答 2

6

该错误基本上表明当您导航到 ProductFilterRoute 时,Ember 需要一个数组。

为什么 Ember 在这里需要一个数组?

  1. 您的路线 (ProductFilterController)的控制器是 ArrayController 类型
  2. 我对coffeescript 不是很熟悉,但是您的模型钩子似乎也返回了一个数组。重要提示:模型钩子只是在通过 Url 进入您的 App 时执行。(这就是为什么您的 Url 手动导航和 href 都可以工作的原因。引用EmberDoc:“您可以实现将 URL 转换为该路由的模型的钩子。”)

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

一个可能的解决方案:

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

模板修改:

<a {{action 'filterProductByAsset' this}}> {{title}} </a>

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)
    }
}
于 2013-03-02T17:51:37.533 回答
1

我怀疑这是问题所在:

assetTypes: (->
  docs = @get('documents')
  docs.getEach 'asset_type_id'
).property('documents')

这看起来会产生一个像这样的数组:

[1,2,3,4,5]

当你真的需要一个响应 id 的对象数组时,例如

object1 = Em.Object.create id: 1
object2 = Em.Object.create id: 2
[object1, object2] #etc

如果你想改变这种行为,你需要查看你链接的路由的序列化钩子,在这种情况下product.filter

关于{{linkTo}}与手动创建的链接,linkTo 助手启用了 js,您应该始终使用它而不是手动链接。当使用 HistoryLocation / pushState 支持时,这会成为一个真正的问题,因为它会强制重新加载整个页面。

这里还有一个问题:你不能像这样观察文件。你必须使用类似的东西property('documents.@each')

于 2013-03-02T17:49:51.767 回答