Backbone.js and built-in one-to-many associations

Application Layout

I am creating an application where you can create polls. Each survey has many questions. I am inserting questions into the survey model (with embeds_many in Mongoid), so the survey might look like this:

 { "id": "4f300a68115eed1ddf000004", "title": "Example Survey", "questions": [ { "id": "4f300a68115eed1ddf00000a", "title": "Please describe your experience with backbone.js", "type": "textarea" }, { "title": "Do you like it?", "id": "4f300a68115eed1ddf00000b", "type": "radiobutton", "options": ["Yes", "Yes, a lot!"] } ] } 

Now there is also a survey editor, which consists of SurveyView , which displays the survey and lists the questions. If I click on one question, a QuestionView message will appear where I can edit the question. And when I'm happy with my poll and I click save, SurveyModel will be sent to the server.

Problem

What is the best way to handle inline association?

If I pass survey.get("questions")[any_index] to QuestionView and the question survey.get("questions")[any_index] , I will have to manually search for question.id in my model and update my model. This seems wrong.

If I create a QuestionsCollection in my SurveyModel (is this possible?). Then I can do things like extracting Question from this collection by id, passing it to the view and when I change the model everything will be updated automatically, but I have to specify the url in the collection and the spine will send separate questions to the server, if everything updated.

Is there any suggestion on how to do this on a trunk basis?

+6
source share
4 answers

You probably have a question Collection inside your SurveyModel.

but you are right in the question, considered as one question (since each question should have its own identifier, you can still find out on the server on which it belongs ...)

then there will be parsing of your json: if you create your collection and models manually, you will not have this problem, but if you add your own JSON, it will not automatically create subdirectories for your model. you will need to specify these things in the overridden parsing method.

+5
source

A way to create inline one-to-many associations in backbone.js

I implemented the answer from @Sander and just wanted to post the code:

 class Survey extends Backbone.Model # Handles the Survey.questions association to parse stuff from the server parse: (resp) -> if @attributes?.questions? @attributes.questions.reset(resp.questions) else resp.questions = new QuestionsCollection(resp.questions) resp # Recollects Survey.questions toJSON: -> attributes = _.clone(@attributes) attributes.questions = attributes.questions.toJSON() attributes 

Then I can do things like:

 survey = Survey.get("my-id") survey.questions.at(0).title = "First question" survey.questions.at(1).title = "Second question" survey.save() 

Which works quite comfortably.

+15
source

I think you can even do it under construction

 class Survey extends Backbone.Model initialize: -> @questions = new QuestionsCollection(@get('questions')) 

You can also expand the model universally to get nested data:

 _.extend Backbone.Model::, deepToJSON: -> obj = @toJSON() _.each _.keys(obj), (key) -> obj[key] = obj[key].deepToJSON() if _.isFunction(obj[key].deepToJSON) obj _.extend Backbone.Collection::, deepToJSON: -> @map (model) -> model.deepToJSON() 
+4
source

Overriding parsing / toJSON is a workable solution. One of the things you need to know about is that the β€œthis” in the parse method is not a model object when the object is retrieved through a collection. Then the syntax is parsed and the result is passed for initialization. The reason you might need β€œthis” to point to a model object is if you want to bind events in the collection. An alternative approach is to replace the set method instead. I put a simple script on Github that demonstrates this approach.

0
source

Source: https://habr.com/ru/post/908233/


All Articles