Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone model state when tied to a form

I'm building a form with Backbone and looking to have it validate its fields on the "blur" event.

Hooking into the event is easy enough, but what I'm curious about is whether or not the model should be updated on blur or only when the form is submitted?

Updating model on blur

  • model.set({...}, {validate:true});
  • if your model has multiple attributes, validation will be run for all of them, every time
  • when creating a new item, the model state isn't as important because it's probably not shared with any other modules yet
  • when editing an item, the model is in this weird outdated/updated state, depending on where the person is in the form. What if the model is being shared between multiple modules?

Updating model on submit

  • can't use model.set() for validation, so the model needs to expose some validation methods (eg MyModel.validZip())
  • on submit, even though all fields have been validated, set() needs to be called to update the model, which will cause validation to happen one more time (not entirely sure this is bad though)

I've read through a couple of relevant Backbone github issues (1, 2, 3) and Backbone devs seem to draw a line between a model and a form.

Additionally, the Backbone.Form plugin appears to keep an internal fields property to track the form fields and when done, call .commit() to update the model.

So it seems like updating the model on submit is the better approach. Is that the experience you've had?

like image 561
jbarreiros Avatar asked Dec 17 '14 00:12

jbarreiros


People also ask

What is backbone in programming?

Backbone. js is a model view controller (MVC) Web application framework that provides structure to JavaScript-heavy applications. This is done by supplying models with custom events and key-value binding, views using declarative event handling and collections with a rich application programming interface (API).

Which is considered the backbone of any HTML document?

js (aka Backbone) is designed to add structure to client-side applications, to avoid a spaghetti-code mess. In the words of Backbone. js: Backbone.

How do I use backbone sync?

<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.2/underscore-min.js" type="text/javascript"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js" type="text/javascript"></script>


2 Answers

Proper UX in forms is tricky. I have tried both of your approaches in the past. In my opinion, there is a third option: always keep a model in-sync with your view's state.

This short video highlights some of my reasoning: http://screencast.com/t/qukIe6XW5.

In this video, I am typing into a form. The form auto-updates to show how many characters I have typed and how many are allowed. It's good UX to to provide instantaneous feedback rather than making the user remove focus from the form, find out they have validation errors, and then come back to the form. In order to achieve this, you'll need to be able to know the state of your view at all times.

But I don't want my model's state to be updated automatically! The user needs to press submit first!

It sounds like introducing another class of models would make your life a lot easier. Consider creating a viewmodel which keeps a reference to the instance of your model. With the introduction of a viewmodel you will be able to record the changes to your view without affecting the state of your model. This helps mitigate the risk of bad things happening and, if anything does go awry, your server will be able to catch the changes and fail with server-side validation.

Here are some links to my source for doing in-place editing:

  • https://github.com/MeoMix/StreamusChromeExtension/blob/master/src/js/foreground/view/prompt/editPlaylistPromptView.js
  • https://github.com/MeoMix/StreamusChromeExtension/blob/master/src/js/foreground/view/prompt/editPlaylistView.js

You'll see that I give EditPlaylistPromptView an EditPlaylistPrompt model which stores a reference to the playlist being edited. However, it doesn't directly modify that playlist while the user is working on the view. It just updates the playlist once it passes validation. Note that I'm not going through the model for validation, but I could be, just slacking on that aspect of it.

Here's a picture of how I like to visualize things. It is completely true that a model should be concerned about a view to enforce separation of concerns. However, that's only when you're working with 3 layers of objects. Be more flexible, introduce a new, intermediary layer called a ViewModel and your life gets simpler:

enter image description here

like image 120
Sean Anderson Avatar answered Oct 20 '22 00:10

Sean Anderson


Updating the model on submit seems like a better approach. Backbone is an MVC framework (more of an MV*, but designed to follow the same principles). That being said, the whole point of controllers is to have a separate layer dedicated to restricting, or controlling, how a user interacts with the data (model). So only letting the user update the model until everything is valid conforms with traditional MVC logic.

Additionally, you're only validating once the user has submitted and essentially said 'this is what I want things to be'. Updating on blur could preemptively validate information.

See wikipedia MVC: "[MVC] divides a given software application into three interconnected parts so as to separate internal representations of information from the ways that information is presented to or accepted from the user"

like image 27
Keenan Lidral-Porter Avatar answered Oct 20 '22 00:10

Keenan Lidral-Porter