为什么 backbone 过滤器 collection 在传递给视图时失败

Why does backbone filter collection fails when passing to view

我有两种过滤方法 collection:

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

byCategory = @projects.byCategory(data)

方法二:这个方法效果很好

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()});

Collection

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

TL;DR

我假设 @projects.byCategory(data) returns 是 Backbone.model 的数组,而视图需要 Backbone.Collection 的实例。在您看来,您可能正在使用 this.collection.models 进行迭代*,而 .models 是一个 属性,您肯定不会在 Backbone.model.[= 的普通数组中找到它53=]

* The argument holds true if you're calling collection.fetch() or maybe even .set(), or any other Backbone.Collection, method


我的直觉(除非你另有说明)是

App.Collections.Projects.byCategory()

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

问题一:为什么通过byCategory = @projects.byCategory(data)会失败?

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

问题 2:为什么 .map() 总是有效?

这个问题的答案并不明显。显然 Backbone.collection.map 会顺利工作,因为 _.map() 默认情况下混合到 Backbone.Collection 中。

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

问题依旧,为什么.get('title')方法在

console.log project.get('title')

工作?给出上面的,很简单。由于您将 Backone.model 的数组传递给 Array.prototype.map(),因此每次迭代的参数是 Backone.model,它会很乐意接受 Backone.model.get().