So I am fighting with this backbone script. Basically what it should do is: when something in the model changes it needs to render the view again.
All goes well, the change event gets triggered and the view responds. but then when I come back in the render, it lost the model and it lost the element ($el) in the view to which the date needs to be rendered
I created a snippet you can find it here:
var APP = {};
APP.items = [{
"id": "id_2",
"alias": "item 2"
}];
APP.newItem2 = {
"id": "id_2",
"alias": "item 2",
"ttile": "here is your title",
"description": "need I say more?"
}
APP.ItemModel = Backbone.Model.extend({
initialize: function (attr) {
console.log(attr);
},
updateStore: function (prod) {
this.set(prod);
}
});
APP.ProductsCollection = Backbone.Collection.extend({
model: APP.ItemModel,
initialize: function (mdls) {
console.log(mdls);
}
});
APP.ItemView = Backbone.View.extend({
initialize: function () {
this.model.on("change", this.render);
this.render();
},
render: function () {
console.log('this: ', this); //this is always known
console.log('render model: ', this.model); //the second time the model is undefined
console.log('el: ', this.$el); //the second time the $el is undefined
var htmlSource = $("#itemContent").html(),
template = Handlebars.compile(htmlSource),
compiled = template(this.model);
this.$el.html(compiled);
},
events: {
"click .clickBtn": "loadData"
},
loadData: function (e) {
this.model.updateStore(APP.newItem2);
}
});
APP.MainView = Backbone.View.extend({
el: "#listContainer",
initialize: function () {
APP.productsCollection = new APP.ProductsCollection(APP.items);
this.render();
},
render: function () {
var that = this,
htmlSource = $("#basicContent").html(),
template = Handlebars.compile(htmlSource),
compiled = template(APP.productsCollection);
this.$el.html(compiled);
APP.productsCollection.models.forEach(function (model) {
new APP.ItemView({
el: "#" + model.attributes.id,
model: model
});
});
}
});
APP.mainView = new APP.MainView();
.maplayer_wrap {
width: 500px;
height: 100px;
background-color: white;
padding: 10px;
margin-top: 10px;
border: 1px solid #CCC;
}
<script src="https://code.jquery.com/jquery-3.2.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.10/handlebars.js"></script>
<div id="listContainer">
</div>
<script id="basicContent" type="text/x-handlebars-template">
{{#each models}}
<div class="maplayer_wrap" id="{{id}}">Loading... </div>
{{/each}}
</script>
<script id="itemContent" type="text/x-handlebars-template">
<span class="maplayer_image">
new data...
</span>
<div class="maplayer_content">
<p class="maplayer_content_head">{{attributes.title}}</p>
<p class="maplayer_content_txt">{{attributes.description}}</p>
</div>
<span class="maplayer_icon">
<i class="fa fa-map-o fa-fw" aria-hidden="false"></i>
</span>
<button class="clickBtn">
click!
</button>
</script>
If you like jsfiddle you can find a copy here: https://jsfiddle.net/rwqwfz8b/50/
How do I solve this problem?
Edit: In the meanwhile I am looking for a solution myself. What I found is the first time I render the view all is well. However, when the model changes and the view renders again it seems like the view thinks it is the model in stead of the view.
Therefor it loses all data and cannot be rendered again.