Aplicación Backbone.js no representa la vista
-
25-10-2019 - |
Pregunta
Encontré Backbone.js hace un par de días, y descubrí que es una herramienta de código bonita para el desarrollo de JavaScript, aunque mi habilidad de JavaScript no es genial. Sin embargo, después de leer la documentación, decidí codificar una aplicación de contacto simple. Guardo los datos de contacto en el navegador LocalStorage. Este es código // código fuente para mi aplicación de contactos
$(function() {
//Contact Model
Contact = Backbone.Model.extend({
//Contact Defaults
defaults : {
first_name : 'First Name',
last_name : 'Last Name',
phone : 'Phone Number'
},
//Constructor(intialize)
//Ensuring each contact has a first_name,last_name,phone
intialize: function(){
if(!this.get("first_name")) {
this.set({"first_name":this.defaults.first_name});
}
if(!this.get("last_name")) {
this.set({"last_name":this.defaults.last_name});
}
if(!this.get("phone")) {
this.set({"phone":this.defaults.phone});
}
}
});
//Contact Collection
//The collection is backed by localstorage
ContactList = Backbone.Collection.extend({
//Model
model : Contact,
//Save all contacts in localstorage under the namespace of "contacts"
localStorage: new Store("contacts")
});
//Create global collection of Contacts
Contacts = new ContactList;
//Contact View
ContactView = Backbone.View.extend({
tagName : "li",
template: _.template($("#item_template").html()),
events : {
"click span.contact-delete": "delete_contact"
},
intialize: function(){
this.bind('change',this.render,this);
this.bind('destroy',this.remove,this);
},
render: function() {
$(this.el).html(this.template(this.model.toJSON()));
this.setContent();
return this;
},
setContent: function() {
var first_name = this.model.get("first_name");
var last_name = this.model.get("last_name");
var phone = this.model.get("phone");
var name = first_name+" "+last_name;
this.$('.contact-name').html(name);
this.$('.contact-phone').html(phone);
},
remove: function() {
$(this.el).remove();
},
delete_contact: function() {
this.model.destroy();
}
});
//The Application
AppView = Backbone.View.extend({
el: $("#contact-app"),
events : {
"click #new-contact #save-button": "createContact"
},
intialize: function() {
Contacts.bind("add", this.addOne, this);
Contacts.bind("reset", this.addAll, this);
Contacts.fetch();
},
// Add a single contact item to the list by creating a view for it, and
// appending its element to the `<ul>`.
addOne: function(contact) {
var view = new ContactView({model: contact});
this.$("#contact-list").append(view.render().el);
},
// Add all items in the **Contacts** collection at once.
addAll: function() {
Contacts.each(this.addOne);
},
// Generate the attributes for a new Contact item.
newAttributes: function() {
return {
first_name : this.$('#first_name').val(),
last_name : this.$('#last_name').val(),
phone : this.$('#phone').val()
};
},
createContact: function() {
Contacts.create(this.newAttributes());
//Reset Form
this.$('#first_name').val('');
this.$('#last_name').val('');
this.$('#phone').val('');
}
});
// Finally,kick things off by creating the **App**.
var App = new AppView;
});
Y esta es mi fuente HTML
<div id="contact-app">
<div class="title">
<h1>Contacts App</h1>
</div>
<div class="content">
<div id="new-contact">
<input name="first_name" placeholder="First Name" type="text" id="first_name"/>
<input name="last_name" placeholder="Last Name" type="text" id="last_name" />
<input name="phone" placeholder="Phone Number" type="text" id="phone" />
<button id="save-button">Create Contact</button>
</div>
<div id="contacts">
<ul id="contact-list">
</ul>
</div>
<div id="contact-stats"></div>
</div>
</div>
<script type="text/template" id="item_template">
<div class="contact">
<div class="contact-name"></div>
<div class="contact-phone"><div>
<span class="contact-delete"></span>
</div>
</script>
Los datos de contacto se guardan en el almacenamiento local, que puedo ver a través de Firebug, pero la vista no se actualiza. Soy nuevo en Backbone.js. ¿Cuál es el problema? No hay errores de JavaScript.
Solución
Intente usar "Agregar" en lugar de 'Crear' para agregar modelos a la colección (no creo que el evento 'Agregar' esté siendo disparado por el método 'Crear').
En vez de
Contacts.create(this.newAttributes());
Usar
Contacts.add(this.newAttributes());
Para guardar el modelo en el almacenamiento local, puede llamar al método Guardar
addOne: function(contact) {
var view = new ContactView({model: contact});
contact.save();
this.$("#contact-list").append(view.render().el);
},
EDITAR:
Otra cosa verifica la ortografía de su método de "intializar", creo que debería ser "inicializar".
Aquí está un jsfiddle, No lo estoy guardando en LocalStorage en el JSFIDDLE, pero eso debería funcionar por usted.
Otros consejos
En el modelo, el defaults
debe ocuparse de los valores predeterminados, el initialize
Las funciones probablemente no sean necesarias; Alguien me corrige en esto si me equivoco.
En su ContractView, es posible que deba cambiar su línea de renderizado a esto en su initialize
método:
this.model.bind('change', _.bind(this.render, this));