在嵌套 JSON (BackboneJS) 中按父节点动态过滤

Posted

技术标签:

【中文标题】在嵌套 JSON (BackboneJS) 中按父节点动态过滤【英文标题】:Dynamically filtering by parent node in nested JSON (BackboneJS) 【发布时间】:2014-06-07 00:11:27 【问题描述】:

我知道问题标题有点混乱,所以请原谅-希望我能解释我的问题。

我有一个像这样的数据结构:


  "_data": 
    "Test Alignment Form": [
      
        "review_form": "Test Alignment Form",
        "rvee_uid": "52",
        "firstName": "Joe",
        "lastName": "Bloggs",
        "status": "NOT_STARTED",
        "status_clean": "Not started"
      ,
      
        "review_form": "Test Alignment Form",
        "rvee_uid": "54",
        "firstName": "Steve",
        "lastName": "Stevenson",
        "status": "NOT_STARTED",
        "status_clean": "Not started"
      ,
      
        "review_form": "Test Alignment Form",
        "rvee_uid": "13",
        "firstName": "Anne",
        "lastName": "Boleyn",
        "status": "COMPLETED",
        "status_clean": "Completed"
      
    ],
    "Another Form": [
      
        "review_form": "Another Form",
        "rvee_uid": "10",
        "firstName": "Luther",
        "lastName": "Vandross",
        "status": "NEVER_TOO_MUCH",
        "status_clean": "Never too much, never too much... duh duh duh"
      ,
      
        "review_form": "Another Form",
        "rvee_uid": "54",
        "firstName": "Steve",
        "lastName": "Stevenson",
        "status": "NOT_STARTED",
        "status_clean": "Not started"
      ,
      
        "review_form": "Another Form",
        "rvee_uid": "13",
        "firstName": "Anne",
        "lastName": "Boleyn",
        "status": "COMPLETED",
        "status_clean": "Completed"
      
    ]
  ,
  "_meta": 
    "generated": 1397642209,
    "length": 62,
    "duration": 3,
    "author": 0
  

而我的代码目前是这样的:

window.app = app = window.app or
  models:      
  collections: 
  views:       
  routes:      
  init:        () ->
    console.log 'Initialised app.'
    app._app = new app.views.table()

#-----------------------------------------------------------------------------#

app.models.form = Backbone.RelationalModel.extend
  defaults:
    firstName:    ""
    lastName:     ""
    review_form:  ""
    rvee_uid:     "0"
    status:       ""
    status_clean: "UNKNOWN"

  initialize: () ->
    console.log "Initialised model 'form'."



app.collections.mainCollection = Backbone.Collection.extend
  model: app.models.form
  url: "data/data.json"
  initialize: (models, options) ->
    console.log "Initialised collection 'mainCollection'."
    @options = options

    @fetch reset: true

    @on "reset", () ->
      console.log "Collection reset!"



app.views.tableItem = Backbone.View.extend

  tagName: 'li'

  template: _.template $('#row').html()

  initialize: () ->
    console.log "Initialised view 'tableItem'."

  render: () ->
    console.log "Rendered view 'tableItem'."
    @$el.html @template @model.toJSON()
    @



app.views.table = Backbone.View.extend

  el: '#table'

  initialize: (data) ->
    console.log "Initialised view 'table'."
    @collection = new app.collections.mainCollection data

    @listenTo @collection, 'reset', () ->
      @render()

  render: () ->
    console.log "Rendered view 'table'."
    @$el.empty()
    console.log @collection.models
    _.each @collection.models, (_item) =>
      @renderItem(_item)

  renderItem: (_item) ->
    item = new app.views.tableItem
      model: _item

    @$el.append item.render().el


#-----------------------------------------------------------------------------#

app.init()

(请记住,我有一个更大的工作版本,但没有嵌套结构,所以这只是用于沙盒)。

无论如何,想象一下我有另一个视图,其中包含一个select 下拉输入,由“测试对齐表单”和“另一个表单”填充。当我选择一个时,我希望返回的模型是该表单的子代。所以,相当于解析出@['_data']['Test Alignment Form']。我也希望能够访问“_meta”对象,例如,我希望能够在另一个视图中打印出生成的日期。有谁知道实现这一目标的任何最佳实践?我一直在拔头发!

谢谢:)

【问题讨论】:

【参考方案1】:

所以.. 嗯,你有一个集合的集合。您的数据是包含表单的集合。表单是条目的集合。

您的表单集合应该包含您的数据结构。

那么它应该制作表单模型。那些表单模型有入口集合。

FormCollection

  parse: (res) ->

    @_meta = res
    _.map res._data, (data, formName) =>
      formName, data  # we have 2 attributes on the form model

FormModel

  initialize: ->
    @on 'reset', ->
      # Since each form also has a collection of entries, we create a collection
      @entries ?= new EntryCollection
      @entries.parent = this # this circular dependency will create memory leaks
      @entries.reset @get('data'), parse: true #remember data is an array

EntryCollection

  parse: (res) ->
    @meta = parent.collection._meta
    res

EntryModel

EntryCollection 内的模型可以访问@collection.meta

您应该注意这种嵌套很容易出现内存泄漏,因此如果您的页面保持打开数天,您应该考虑delete @parent等,但您可能不需要担心。

这只是第一次尝试,您可能会进行改进,但如果您要构建更多,您希望为每个对象创建一个模型,为每个数组创建一个集合。你的 _data 实际上是数组。

你有

"_data": 
  "Test Alignment Form": [
    
      "review_form": "Test Alignment Form",
      "rvee_uid": "52",
      "firstName": "Joe",
      "lastName": "Bloggs",
      "status": "NOT_STARTED",
      "status_clean": "Not started"
    ,
    
      "review_form": "Test Alignment Form",
      "rvee_uid": "54",
      "firstName": "Steve",
      "lastName": "Stevenson",
      "status": "NOT_STARTED",
      "status_clean": "Not started"
    ,
    
      "review_form": "Test Alignment Form",
      "rvee_uid": "13",
      "firstName": "Anne",
      "lastName": "Boleyn",
      "status": "COMPLETED",
      "status_clean": "Completed"
    
  ],
  "Another Form": [
    
      "review_form": "Another Form",
      "rvee_uid": "10",
      "firstName": "Luther",
      "lastName": "Vandross",
      "status": "NEVER_TOO_MUCH",
      "status_clean": "Never too much, never too much... duh duh duh"
    ,
    
      "review_form": "Another Form",
      "rvee_uid": "54",
      "firstName": "Steve",
      "lastName": "Stevenson",
      "status": "NOT_STARTED",
      "status_clean": "Not started"
    ,
    
      "review_form": "Another Form",
      "rvee_uid": "13",
      "firstName": "Anne",
      "lastName": "Boleyn",
      "status": "COMPLETED",
      "status_clean": "Completed"
    
  ]
,

应该是

"_data": [
  
    name: "Test Alignment Form",
    contents: [
      
        "review_form": "Test Alignment Form",
        "rvee_uid": "52",
        "firstName": "Joe",
        "lastName": "Bloggs",
        "status": "NOT_STARTED",
        "status_clean": "Not started"
      ,
      
        "review_form": "Test Alignment Form",
        "rvee_uid": "54",
        "firstName": "Steve",
        "lastName": "Stevenson",
        "status": "NOT_STARTED",
        "status_clean": "Not started"
      ,
      
        "review_form": "Test Alignment Form",
        "rvee_uid": "13",
        "firstName": "Anne",
        "lastName": "Boleyn",
        "status": "COMPLETED",
        "status_clean": "Completed"
      
    ],
  ,
  
    name: "Another Form",
    contents: [
      
        "review_form": "Another Form",
        "rvee_uid": "10",
        "firstName": "Luther",
        "lastName": "Vandross",
        "status": "NEVER_TOO_MUCH",
        "status_clean": "Never too much, never too much... duh duh duh"
      ,
      
        "review_form": "Another Form",
        "rvee_uid": "54",
        "firstName": "Steve",
        "lastName": "Stevenson",
        "status": "NOT_STARTED",
        "status_clean": "Not started"
      ,
      
        "review_form": "Another Form",
        "rvee_uid": "13",
        "firstName": "Anne",
        "lastName": "Boleyn",
        "status": "COMPLETED",
        "status_clean": "Completed"
      
    ],
  ,
];

除非我有误解,但我认为Another Form 是用户生成的.. 可能有无限的形式,对吧?

关于您的跟进

FormView

  render: ->

    @$el.empty().append formTemplate(this)
    @model.entries.each (model) =>

      # if you need more speed or re-render often, you can cache these views later
      entryView = new EntryView model
      # assumes you have an entries-container in your form template
      @$('.entries-container').append entryView.render().el

【讨论】:

感谢您的回复!我得看一场戏然后回复你。是的,表格和条目的数量可以是任意长度。顺便说一句,_.map @_data, (data, formName) => 行实际上应该是 _.map res._data, (data, formName) => 吗?还是我错过了什么?再次感谢。 啊,是的,应该,但你可以在服务器端修复它并完全删除整个map 是的,没错。所以,如果你不介意进一步的帮助,我还有一个问题。它似乎已经完成了子集合......有点。但我正在努力获得某些视图来显示嵌套集合。我开始在Marionette做到这一点,看看它是否有帮助,这是源:gist.github.com/MaffooBristol/11395118(参见第90行) - 我希望下拉列表以表单名称填充,并且选择时,我希望表格(以及任何其他未来视图)填充数据。请问我该怎么做?谢谢! 那么你会有一个FormView 和一个EntryViewFormView 将渲染 EntryViews 并在速度成为问题时缓存它们,但这很容易导致更多的内存泄漏,除非你取消缓存它们或者浏览器对循环依赖足够好。无论如何,总有 5 种方法可以做某事。最好的学习方法是用错误的方法一段时间,然后看看你有多愚蠢,不要再犯了,所以试一试吧! 好的,我会玩一些。是的,我知道,但不幸的是,公司老板和必须与客户交谈的人不太愿意使用错误的方法;)在任何赏金顺便说一句之前,我会坚持一段时间,但我很感激帮助!

以上是关于在嵌套 JSON (BackboneJS) 中按父节点动态过滤的主要内容,如果未能解决你的问题,请参考以下文章

如何在Postgresql中按嵌套数组的重复值分组?

如何在javascript中按id嵌套数据过滤和分组?

与backbonejs模型对象json表示的问题

BackboneJs 中的多个路由器与单个路由器

在深层嵌套对象中按特定键查找所有值

在嵌套选择查询中按条件分组后加入