I know the question title is a bit confusing so please excuse me- hopefully I can explain my problem.
I have a data structure like so:
{
"_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
}
}
And my code is currently like this:
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()
(Please bear in mind that I have a bigger, working version, but with an un-nested structure, so this is just for sandboxing).
Anyway, so imagine that I have another view that contains a select
dropdown input, populated by "Test Alignment Form" and "Another Form". When I select one, I want the models returned to be children of that form. So, the equivalent of parsing out @['_data']['Test Alignment Form']
. I want to be able to have access to the "_meta" object too, as I would like to be able to print out the generated date in another view, for example. Does anyone know of any best practices for achieving this? I've been pulling my hair out!
Thanks :)
So.. hmm you have a collection of collections for one. Your data is a collection that contains forms. Forms are a collection of entries.
your form collection should take in your data structure.
then it should make form models. those form models have entry collections.
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
models within EntryCollection
can access @collection.meta
You should note that this sort of nesting is prone to memory leaks, so if your page stays open for days, you should consider delete @parent
, etc, but you might not need to worry about it.
This is just a first shot at it, you could probably make improvements, but if you will be building this up more, you want to have a model for every object and a collection for every array. your _data is actually array.
you have
"_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"
}
]
},
it should be
"_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"
}
],
},
];
unless I am misunderstanding, but I think Another Form
is user generated.. there could be infinite forms right?
In regard to your follow up
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With