Reputation: 15992
Been reading up on Backbone.js where they give this example.
var Sidebar = Backbone.Model.extend({
promptColor: function() {
var cssColor = prompt("Please enter a CSS color:");
this.set({color: cssColor});
}
});
window.sidebar = new Sidebar;
sidebar.on('change:color', function(model, color) {
$('#sidebar').css({background: color});
});
sidebar.set({color: 'white'});
sidebar.promptColor();
A prompt asks you for a color, when you enter one, the sidebar's color changes. My question is, why should I prefer the above code to the code below? I think it has something to do with code structure but I can't say exactly why. Is it because this example is too simple, and the advantages of writing the above code only appear when an application becomes large?
Ignore the backbone code for initializing the starting color and calling promptColor()
, i left it in there for context.
function promptColor(){
var cssColor = prompt("please enter a css color:");
$('#sidebar').css({background:cssColor})
}
Upvotes: 1
Views: 128
Reputation: 43156
First of all the given example is a poor one showing DOM
manipulation inside a model..! No. that is not where you manipulate DOM
.
The key thing to note is that, backbone gives structure to your application, lets you separate concerns easily.
If you see the below example (again a poor, sidebar thingy example), the presentation logic is entirely handled by Backbone.View
instance.
DOM
and chances of conflicts are very less since we work with each view's element inside it.instance.remove()
to remove the event handlers and element from DOM
The state of a component and related data are stored in Backbone.Model
instances.
var Color = Backbone.Model.extend({
defaults: {
color: 'white',
accepted: ['white', 'red', 'green', 'blue']
},
validate: function(attrs) {
if (this.get("accepted").indexOf(attrs.color) < 0)
return new Error();
}
});
var Sidebar = Backbone.View.extend({
attributes: {
class: 'sidebar'
},
initialize: function() {
this.listenTo(this.model, 'change:color', this.switchColor);
this.render();
},
events: {
'input .color': 'updateColor',
'click .close': 'remove'
},
render: function() {
this.$el.append($('#sidebar').html());
return this;
},
updateColor: function(e) {
this.model.set({
color: $(e.target).val()
}, {
validate: true
});
},
switchColor: function(model, color) {
this.$el.css({
background: color
});
}
});
for (var i = 0; i < 3; i++) {
$('body').append(new Sidebar({
model: new Color()
}).el);
}
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%
}
.sidebar {
display: inline-block;
box-sizing: border-box;
position: relative;
height: 100%;
padding: 5px 15px 5px 0;
margin: 0 2px;
border: 5px solid dodgerblue
}
.close {
display: inline-block;
position: absolute;
top: 5px;
right: 0;
height: 18px;
text-decoration:none;
border: 0px solid grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.2.3/backbone-min.js"></script>
<script type="text/template" id="sidebar">
<input type="text" class="color" placeholder="enter bg color... red, green, blue"/>
<a href="#" class="close">✖</a>
</script>
Of course you can directly modify the color without setting it to a model in this particular example, the point is to show how you separate the concerns of components in real world applications.
The models job is to hold the data and make sure it's valid at all times. View presents the data to user and lets him work with it. Model acts as the source of truth.
If you use plain js, you'll find that your data and DOM
are tightly coupled and you'll have to write custom logic to huge lot of stuff that backbone provides out of the box... like it's event system... router... collection... sync API.. (and we're not using any of them apart from the tiny use of event system which is why its a poor example)
To answer your question: "Is it because this example is too simple" - Yes. People normally doesn't go after an MV* js framework to set up a prompt... This is like using a hand grenade to open a plastic door like Alexander mentioned.
You'll see backbone excels when you want to perform CRUD operations, handle routing, communicate with backend etc. For eg to send the latest color (be it any data) all you need to do is add a url
property to the model declaration, and call model.save()
. How cool is that..?
Upvotes: 2
Reputation: 97
For this concrete example as it mentioned here it does not make any sense, but let's say if you want to synchronize your collection of elements like [{id: 1, body: "Hello World"}, {id: 2, body: "Hello World!"}]
receive a new elements that appeared on the backend and quickly render it with a template you defined, or let's say to update some element and want to keep it syncronized with the backend. It is much more easier to do with frameworks such like Backbone.js
On my opinion it won't prevent you from the spaghetti code of course because everything depends on you. But, it can help you to split up your logic and make it easier to read for the team members you might have.
To have a better understanding of Backbone.js I would recommend you to check out this tutorial: http://backbonejs.org/docs/todos.html
Upvotes: 0
Reputation: 863
For that simple example it does not make sense to use a framework. That's like using an IDE to write a 10 lines script or using a grenade to open a door. Maybe you want to have a look at some projects that use backbone, or the best thing would be to think of a bigger task and then come up with a backbone vs. vanillaJS implementation.
From my personal experience I often encounter over or under complication of the whole project - you need to find the right tools for your job or you end up with spaghetti code or a monolitic structure for simple tasks.
Upvotes: 0