如何清除数组的内容并替换嵌套集合的新内容?

时间:2013-05-18 16:51:10

标签: backbone.js coffeescript marionette

我有一个Project模型,它有一个嵌套的ProjectSlides集合。项目幻灯片是我想要(迭代)显示特定于所点击的特定项目的图像。

我可以点击项目列表中的项目名称,它会显示图像,正确迭代每个图像。如果我点击另一个项目名称,我希望清除第一个项目图像(项目幻灯片)的数组,并替换为我点击的新项目的项目幻灯片图像。但是,属于第一个项目的项目幻灯片的图像会清除,第二个项目的项目幻灯片图像会附加到数组中。

问题

当我点击另一个项目并使用新项目的项目幻灯片图像填充数组时,如何让阵列清除其内容?

在我的项目控制器中,我有以下代码:

显示项目列表:

showProjectList: (projects) ->
  projectListView = @getProjectListView projects
  Demo.AboutApp.Show.on "project-name:link:clicked", (project) =>
    console.log project
    @showProject project # passes project model that was clicked on from another view

  @projectsLayout.projectListRegion.show projectListView

获取点击的特定项目:

showProject: (project) ->
  console.log project
  console.log project.get('project_slides')

  newProjectView = @getProjectDetailsView project
  @projectsLayout.projectDetailsRegion.show newProjectView
  console.log slides
  # When I click on another project name, how can I check to see if the array exists? 
  # If the array exists, then set its length to 0 (to empty the previous project's nested collection), 
  # and then add the nested collection project slides of the other project project I clicked on? 
  # Is there some way to scope an array based on an event? That event would create the array, if one doesn't exist, 
  # or if it does exist, empty its contents and replace? I'm so lost.
  project_slides = project.get('project_slides')  # shows project_slides
  slides = (slide for slide in project_slides) # creates the slides array, placing each member of the project slides nested collection in the array. 
  console.log "slides: #{slides}"
  i = 0
  len = slides.length

  callback = ->
    slide = slides[i] # gets the current iteration of the slides array
    slideView = Demo.ProjectsApp.Show.Controller.getSlidesView slide # creates the view
    Demo.ProjectsApp.Show.Controller.projectsLayout.projectSlidesRegion.show slideView # appends the view to the projectsSlideRegion         
    console.log slide
    i++
    i = 0 if i >= len
    return

  setInterval callback, 5000

  slideView = @getSlidesView slides
  @projectsLayout.projectSlidesRegion.show slideView

查看代码:

class Show.ProjectName extends Backbone.Marionette.ItemView
  template: JST["backbone/apps/projects/templates/_project_name_on_project_list"]
  tagName: "li"

  events:
    "click a.project-link" : -> 
      Demo.AboutApp.Show.trigger "project-name:link:clicked", @model

  triggers:
    "click .project-link" : "project:link:clicked" 

 class Show.ProjectSlideList extends Backbone.Marionette.ItemView
   template: JST["backbone/apps/projects/templates/_project_slide"]
   tagName: "li"
   itemViewContainer: "project-slides"
   initialize: ->
     console.log "ProjectSlideList View initialized"
     console.log this

   modelEvents:
     "add" : "render"
     "change" : "render"

型号&集合:

class Entities.Project extends Backbone.Model
  url: -> Routes.project_path(id)

class Entities.ProjectsCollection extends Backbone.Collection
  model: Entities.Project
  url: -> Routes.projects_path()

5/22/13控制器中的最终代码:

showProjectList: (projects) ->
  projectListView = @getProjectListView projects
  Demo.AboutApp.Show.on "project-name:link:clicked", (project) =>
    clearInterval @timer # <-- this is important; gets rid of previous project
    @showProject project

  @projectsLayout.projectListRegion.show projectListView

  # Project id

showProject: (project) ->
  console.log project
  project_slides = project.get('project_slides')  
  newProjectView = @getProjectDetailsView project
  @projectsLayout.projectDetailsRegion.show newProjectView
  slideIndex = -1
  slides_length = project_slides.length

  getNextSlide = ->
    console.log project
    console.log project_slides
    slideIndex++
    slide = project_slides[slideIndex]
    slideIndex = 0 if slideIndex >= slides_length
    console.log slide
    slideView = Demo.ProjectsApp.Show.Controller.getSlidesView slide
    Demo.ProjectsApp.Show.Controller.projectsLayout.projectSlidesRegion.show slideView
    return

  @timer = setInterval getNextSlide, 5000

我在后端使用Rails和rabl gem。这允许我将project_slides作为子集合传递给父项目。换句话说,project_slides已经是project_slide对象的数组。我只需要间隔迭代它们。

Project {cid: "c32", attributes: Object, collection: ProjectsCollection, _changing: false, attributes: Object}
  detail: "first project details"
  id: 1
  logo: "project-icon.png"
  name: "First Project Name"
  problem: "The First Project's Problem Description"
  project_slides: Array[4]
    0: Object
      avatar: "first_image.png"
      caption: "first image's caption"
      id: 1
      project_id: 1
     __proto__: Object
    1: Object
    2: Object
    3: Object
      length: 4
  cid: "c32"
  collection: ProjectsCollection
  id: 1

当我点击一个新项目时,marionette js会处理僵尸并填充正确的数据。已经通过一个幻灯片集合时无需创建另一个幻灯片集合。伙计,我看不到森林里的树木。

2 个答案:

答案 0 :(得分:1)

我认为你应该考虑将幻灯片存储在一个集合中。那么,你所要做的就是

slides.reset(project_slides)

使用集合在Marionette中特别有用,因为当集合触发“重置”事件时,collectionView将自行重新呈现。

如果您想了解有关使用集合视图的更多信息,请查看http://samples.leanpub.com/marionette-gentle-introduction-sample.pdf中的第21-31页(完全披露:我是作者)

答案 1 :(得分:0)

我在后端使用Rails和rabl gem。这有助于将project_slides作为子集合作为json传递给父项目。换句话说,project_slides已经是project_slide对象的数组。我只需要间隔迭代它们。当我点击一个新项目时,marionette js会处理僵尸并填充正确的数据。已经通过一个幻灯片集合时无需创建另一个幻灯片集合。伙计,我看不到森林里的树木。