为什么骨干过滤器集合在传递给视图时失败

时间:2015-01-17 06:44:52

标签: javascript ruby-on-rails backbone.js coffeescript

我有两种方法来过滤集合:

方法1:当我将此方法传递给视图时,使用此方法失败。

byCategory = @projects.byCategory(data)

方法2:此方法非常有效。

byCategory = new App.Collections.Projects(@projects.byCategory(data))


当我映射byCategory并获得标题时,这两种方法都有效:

byCategory.map (project) ->
  console.log project.get('title')


当我将它传递给视图时,第二种方法有效。但第一种方法失败了:

view = new App.Views.ProjectsCarousel(collection: byCategory)
$('.slides').html(view.render().el);

我的问题是:为什么?当我将它传递给视图时,为什么第一个失败,为什么第二个工作?第一个产生错误日志:TypeError: _ref is undefined


完整代码:

路由器

class App.Routers.PortfolioRouter extends Backbone.Router
  routes:
    '': 'index'

  index: ->
    controls = new App.Views.ProjectsControls({el: '#list', projects: new App.Collections.Projects()});

收藏

class App.Collections.Projects extends Backbone.Collection
  url: '/de/projects'

  byCategory: (cat) ->
    return @where category: cat

浏览

class App.Views.ProjectsControls extends Backbone.View

  events:
    'click a': 'selectCategory'

  initialize: (options) ->
    @projects = options.projects
    @projects.fetch()

  selectCategory: (event) ->
    event.preventDefault()

    data = $(event.currentTarget).attr('data-category')
    # This method fails when I pass it to the view
    # byCategory = @projects.byCategory(data)
    # This method works very well, why does it work and the previous no?
    byCategory = new App.Collections.Projects(@projects.byCategory(data))

    # it works with both methods
    byCategory.map (project) ->
      console.log project.get('title')

    view = new App.Views.ProjectsCarousel(collection: @projects)
    $('.slides').html(view.render().el);    



class App.Views.ProjectsCarousel extends Backbone.View
  template: JST['projects/carousel']

  render: ->
    @$el.html(@template(projects: @collection))
    this

模板

<% for project in @projects.models: %>
  <%= project.get('title') %>
<% end %>

1 个答案:

答案 0 :(得分:1)

TL; DR

我假设@projects.byCategory(data)返回Backbone.model数组,而视图需要Backbone.Collection的实例。在您的视图中,您可能正在使用this.collection.models进行迭代*而.models是一个您在Backbone.model的简单数组中无法找到的属性。

  

*如果您拨打collection.fetch()或甚至.set()或任何其他Backbone.Collection方法

,则该参数成立

我的直觉(除非你另有说法)就是那个

App.Collections.Projects.byCategory()

可能会通过Backnone.model.map()返回.pluck()的数组。这个假设将回答您的问题并满足您的.map()测试。

问题1:为什么传递byCategory = @projects.byCategory(data)失败?

因此,如果我的假设是正确的,那么byCategory变量只不过是Backbone.model的JavaScript数组。这不是Backbone在使用Backbone.View.collection属性时所期望的,例如当您执行fetchset或只是尝试迭代collection.models时(并且简单model数组不带.models道具。

问题2:为什么.map()始终有效?

答案并不明显。显然,Backbone.collection.map可以顺利运行,因为默认情况下_.map()会混合到Backbone.Collection

.map()byCategory === @projects.byCategory(data)起作用的原因取决于两件事。 1. byCategory是一个数组,因此,我假设您正在使用符合ECMASCRIPT 5标准的浏览器Array.prototype.map()。并且它接受与_.map()中的混合相同的链接约定,并采用与Array相同的_.map()参数。因此,实际上,您很容易被误以为您正在使用Backbone.collection.map(),而实际上您正在使用Array.prototype.map()

问题仍然存在,为什么

中的.get('title')方法
console.log project.get('title')

工作?给出上述,这很简单。由于您传入了Backone.modelArray.prototype.map()的数组,因此每次迭代中的参数都是Backone.model,它将很乐意接受Backone.model.get()