On Github tsareg / Data-binding-for-Backbone.js
Автор Константин Цареградский
Backbone.js - мощный фреймворк, но...
очень часто приходиться решать простейшие задачи не самым простым образом.
Есть форма редактирования имени и фамилии пользователя, из них генерируется полное имя.
First Name:
Last Name:
Full Name:
Set 'firstName' and 'lastName' to modelFirst Name:
Last Name:
Full Name: <%- firstName %> <%- lastName %>
var FullNameView = Backbone.View.extend({ template: _.template($("script[type='text/template']").html()), events: { "change #firstName": "updateFirstName", "change #lastName": "updateLastName" }, initialize: function () { this.listenTo(this.model, "change:firstName change:lastName", this.render); }, render: function () { this.$el.html(this.template(model.toJSON())); return this; }, updateFirstName: function () { this.model.set("firstName", this.$("#firstName").val()); }, updateLastName: function () { this.model.set("lastName", this.$("#lastName").val()); } }); var model = new Backbone.Model({firstName: "Luke", lastName: "Skywalker"}), view = new FullNameView({model: model, el: $("#container")}); view.render();
Процесс связывания пользовательского интерфейса приложения с бизнес-логикой.
Эта концепция активно используется в таких популярных фреймворках как AngularJS, KnockoutJS и многих других.
First Name:
Last Name:
Full Name:
var ViewModel = function(first, last) { this.firstName = ko.observable(first); this.lastName = ko.observable(last); }; ko.applyBindings(new ViewModel("Luke", "Skywalker"));
First Name:
Last Name:
Full Name: {{firstName}} {{lastName}}
function ctrlName($scope) { $scope.firstName = "Luke"; $scope.lastName = "Skywalker"; }
К сожалению, из коробки Backbone не предоставляет такой функциональности. Однако существует множество сторонних решений:
First Name:
Last Name:
Full Name:
var ModelBindingView = Backbone.View.extend({ template: $("script[type='text/template']").html(), render: function() { this.$el.html(this.template); Backbone.ModelBinding.bind(this); return this; } }); var model = new Backbone.Model({ firstName: "Luke", lastName: "Skywalker" }), view = new ModelBindingView({ model: model, el: $("#container") }); view.render();
First Name:
Last Name:
Full Name:
var ModelBinderView = Backbone.View.extend({ template: $("script[type='text/template']").html(), initialize: function() { this.modelBinder = new Backbone.ModelBinder(); }, render: function() { this.$el.html(this.template); this.modelBinder.bind(this.model, this.el); return this; } }); var model = new Backbone.Model({ firstName: "Luke", lastName: "Skywalker" }), view = new ModelBinderView({ model: model, el: $("#container") }); view.render();
First Name:
Last Name:
Full Name:
var DataBindingView = Backbone.View.extend({ template: $("script[type='text/template']").html(), render: function() { this.$el.html(this.template); return this; } }); var model = new Backbone.Model({ firstName: "Luke", lastName: "Skywalker" }), view = new DataBindingView({ model: model, el: $("#container") }), modelBinder = new Backbone.ModelBinder(view, model); modelBinder.watch('value: firstName', { selector: '[name="firstName"]' }); modelBinder.watch('text: firstName', { selector: '#firstName' }); modelBinder.watch('value: lastName', { selector: '[name="lastName"]' }); modelBinder.watch('text: lastName', { selector: '#lastName' }); view.render();
First Name:
Last Name:
Full Name:
var StickitView = Backbone.View.extend({ template: $("script[type='text/template']").html(), bindings: { '[name=firstName]': 'firstName', '[name=lastName]': 'lastName', '#fullName': { observe: ['firstName', 'lastName'], onGet: function(values) { return values[0] + ' ' + values[1]; } } }, render: function() { this.$el.html(this.template); this.stickit(); return this; } }); var model = new Backbone.Model({ firstName: "Luke", lastName: "Skywalker" }), view = new StickitView({ model: model, el: $("#container") }); view.render();
First Name:
Last Name:
Full Name:
var EpoxyView = Backbone.Epoxy.View.extend({ template: $("script[type='text/template']").html(), computeds: { fullNameDisplay: function() { return this.getBinding("firstName") + " " + this.getBinding("lastName"); } }, render: function() { this.$el.html(this.template); this.applyBindings(); return this; } }); var model = new Backbone.Model({ firstName: "Luke", lastName: "Skywalker" }), view = new EpoxyView({ model: model, el: $("#container") }); view.render();
First Name:
Last Name:
Full Name:
var RivetsView = Backbone.View.extend({ template: $("script[type='text/template']").html(), fullName: function() { return this.model.get("firstName") + " " + this.model.get("lastName"); }, render: function () { this.$el.html(this.template); rivets.bind(this.$el, { model: this.model, view: this }); return this; } }); var model = new Backbone.Model({firstName: "Luke", lastName: "Skywalker"}), view = new RivetsView({model: model, el: $("#container")}); view.render();
rivets.adapters[':'] = { observe: function(obj, keypath, callback) { obj.on('change:' + keypath, callback) }, unobserve: function(obj, keypath, callback) { obj.off('change:' + keypath, callback) }, get: function(obj, keypath) { return obj.get(keypath) }, set: function(obj, keypath, value) { obj.set(keypath, value) } };
First Name:
Last Name:
Full Name:
var KnockbackViewModel = function(model) { this.firstName = kb.observable(model, 'firstName'); this.lastName = kb.observable(model, 'lastName'); this.fullName = ko.computed((function() { return "" + (this.firstName()) + " " + (this.lastName()); }), this); }; var model = new Backbone.Model({ firstName: "Luke", lastName: "Skywalker" }), viewModel = new KnockbackViewModel(model); $('#container').html($("script[type='text/template']").html()); ko.applyBindings(viewModel, $('#container')[0]);
Эта презентация доступна по адресу - http://tsareg.github.io/Data-binding-for-Backbone.js/, sources - https://github.com/tsareg/Data-binding-for-Backbone.js
Рабочие примеры находятся тут - http://tsareg.github.io/Data-binding-for-Backbone.js/samples/, sources - https://github.com/tsareg/Data-binding-for-Backbone.js/tree/master/samples
Презентация создана с помощью Reveal.js