#javascript #jquery #html #css #backbone.js
#javascript #jquery #HTML #css #backbone.js
Вопрос:
Я пытаюсь научиться Backbone.js и теперь я использовал пример на этой странице, чтобы создать представление из коллекции. Для этого я использую коллекцию:
var ContactEventCollection = Backbone.Collection.extend({
initialize: function(models, options) {
this.id = options.id;
this.lastContactEventId = options.lastContactEventId;
},
url: function() {
return 'ticket/' this.id '/contact-events/' this.lastContactEventId;
}
});
одно представление для диалога и одно для события контакта (событие контакта — это в основном сообщение):
var ConversationView = Backbone.View.extend({
render: function(){
this.collection.each(function(contactEvent){
var contactEventView = new ContactEventView({model: contactEvent});
this.$el.append(contactEventView.render().el);
}, this);
return this;
}
});
var ContactEventView = Backbone.View.extend({
template: _.template($('#contact-event-template').html()),
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
ссылка #contact-event-template
выглядит следующим образом:
<script type="text/template" id="contact-event-template">
<div class="user-message"><%= text %></div>
</script>
Затем я пытаюсь добавить ее к этому div ( <div id="put-conversation-here">put the conversation here!</div>
):
var contactEventCollection = new ContactEventCollection([], {id: 1, lastContactEventId: 0});
contactEventCollection.fetch();
console.log(contactEventCollection);
var conversationView = new ConversationView({collection: contactEventCollection});
console.log(conversationView);
$('#put-conversation-here').append(conversationView.render().el);
В консоли я вижу, что conversationView выглядит как изображение ниже. Странно то, что у меня есть коллекция, и у меня есть представление, которое включает в себя все эти модели, но то, что добавляется, — это просто пустое: <div></div>
(даже не с class="user-message"
).
Я также пытался this.model.toJSON()
заменить простым объектом: {text: "some text"}
, но безрезультатно. К настоящему времени я полностью потерян и нуждаюсь в любой помощи, которую я могу получить. Если бы я мог, я бы немедленно назначил награду за это, но, к сожалению, мне приходится ждать два дня, прежде чем делать это.
Кто-нибудь знает, где я здесь ошибаюсь? Любая помощь, советы или рекомендации приветствуются!
Комментарии:
1. Может быть
contactEventCollection.fetch();
, это называется асинхронным, и перед выборкой данных ваш html отображается? Возможно, вы захотите использовать$.when(contactEventCollection.fetch()).done(function(){html population});
, но не уверены в этом.2. @Pushkar — Вы, сэр, просто потрясающие. Вот и все, спасибо!
3. Я не мастер, только начал его использовать. Мы используем handlebar.js . Пожалуйста, отметьте сообщение как ответ.
Ответ №1:
Это contactEventCollection.fetch();
называется асинхронным, и перед извлечением данных ваш HTML-код отображается.
Возможно, вы захотите использовать
$.when(contactEventCollection.fetch()).done(function(){html population});
Ответ №2:
Collection.fetch
вызывается асинхронно, поэтому ваш результат еще не существует, когда вы пытаетесь получить к нему доступ.
«Основной способ» сделать это — прослушать событие и убедиться, что ваше представление будет работать правильно, независимо от того, в каком состоянии находится коллекция.
В идеале ваше представление охватывает полный жизненный цикл вашей коллекции, поэтому оно всегда представляет текущее состояние:
var ConversationView = Backbone.View.extend({
initialize: function () {
// add a view when a model is added to the collection.
this.listenTo(this.collection, 'add', this.addContactEventView);
},
render: function () {
// create views for all existing models
this.collection.each(addContactEventView, this);
return this;
},
addContactEventView: function (model) {
var contactEventView = new ContactEventView({model: contactEvent});
this.$el.append(contactEventView.render().el);
// remove the view when model destroys.
contactEventView.listenTo(model, 'remove', contactEventView.remove);
}
});
Ответ №3:
В этом случае у вас может быть такой код. (код в coffeescript)
// Внутри вашего представления.
template ://receive the template html in you case ('#contact-event-template')
initialize:->
@listOfContact = ''
@collection = new ContactEventCollection()
@collection.on 'triggeredEvent', @render, @
@collcetion.getConversations()
render:->
@collection.each (model) =>
@listOfContact = @template(item.toJSON())
@$el.html(@listOfContact)
Таким образом, у вас есть только один доступ к DOM, избегая перехода туда для каждого элемента вашей коллекции, это более эффективно 🙂