I’m starting to learn backbone.js and I’ve built my first page and I want to know If I’m going down the ‘correct’ path (as much as there is ever a correct path in software).
Is it possible to get the model properties (attributes) to automatically bind to the html elements?
The html:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>settings page</title>
<link rel="stylesheet" type="text/css" href="../Content/theme.css" />
<script language="javascript" src="../Scripts/jquery-1.7.1.js"></script>
<script language="javascript" src="../Scripts/underscore.js"></script>
<script language="javascript" src="../Scripts/backbone.js"></script>
<script language="javascript" src="../Scripts/settings.js"></script>
</head>
<body>
<div style="width:95%;margin:10px;padding:10px;background-color:#ffffff;color:#000000;padding-bottom:8px;padding-right:5px;padding-top:4px;float:left;">
<h1>
Settings...
</h1>
Server URL (cloud based API):
<br />
<input id="settings-service-url" type="text" size="100" />
<br />
<br />
Timeout:
<br />
<input id="settings-timeout" type="text" size="100" />
<br />
<br />
<button id="update-settings">Update Settings</button>
</div>
</body>
</html>
Javascript:
$(document).ready(function () {
if (typeof console == "undefined") {
window.console = { log: function () { } };
}
Settings = Backbone.Model.extend({
defaults: {
ServiceUrl: "",
Timeout: 0
},
url: function () {
return '/settings';
},
replaceServiceUrlAttr: function (url) {
this.set({ WisdomServiceUrl: url });
},
replaceTimeoutAttr: function (timeout) {
this.set({ Timeout: timeout });
}
});
SettingsView = Backbone.View.extend({
tagName: 'li',
events: {
'click #update-settings': 'updateSettings'
},
initialize: function () {
_.bindAll(this, 'render');
this.settings = new Settings;
this.settings.fetch({ success: function () {
view.render(view.settings);
}
});
},
updateSettings: function () {
view.settings.replaceServiceUrlAttr($('#settings-service-url').val());
view.settings.replaceTimeoutAttr($('#settings-timeout').val());
view.settings.save();
},
render: function (model) {
$('#settings-wisdom-service-url').val(model.get("WisdomServiceUrl"));
$('#settings-timeout').val(model.get("Timeout"));
}
});
var view = new SettingsView({ el: 'body' });
});
There are a mistake in your view. First of all, it’s common practice to pass the model as parameter when you create a new view:
now you can access your model by
this.modelin your view.Next thing is the use of the variable
viewin your view. Using Backbone’s View means you can have multiple instances of one View class. So callingnew SettingsView()creates an instance of your view. Let’s think about having two instances of your view:Whenever you call
view.settings.save();in one of your instances it will always call the method in the first view instance because it’s bound the variable name “view”. So all you have to do usethisinstead ofview:SettingsView = Backbone.View.extend({
Using both settings methods in your model doesn’t make much sense at the moment as they just call set. So you could call set on the model directly.
Also using
tagName: 'li'and inserting an element will not work as you expected. Using tagName only has an effect if you don’t insert an element into the constructor. In this case backbone will create a new element using the tagName. Otherwise the element of the view is the one you passed into the constructor.