sergey.sergeyd2016 sergey.sergeyd2016 - 3 months ago 21
Javascript Question

Unable to click on the news in the tape

Please help fix the script. JSFIDDLE

I wrote a simple script that displays news feed from the json. After clicking on a particular news opens a modal window wich contain text of the news.

But modal window always contain the same text. I need that after clicking on various news item, modal window display variuos news text

view news feed:

APP.NewsTapeView = Backbone.View.extend({

initialize: function() {
this.collection = new APP.NewsModelsCollection();
this._fillCollection();

this.render();
},

template: _.template($('#newsTapeTpl').html()),

render: function () {
this.$el.html(this.template());
this._createNewsUnits();

return this;
},

_createNewsUnits: function () {
this.collection.each(function (news) {
var newsUnitView = new APP.NewsUnitView({model: news});
$(this.$('#newsList')).append(newsUnitView.render().el);
}, this);
},

_fillCollection: function () {
var self = this;

$.each(APP.CONFIG.values, function(key, val) {
// console.log(val.title);
// console.log(val.description);
// console.log(val.poster);

var newsModel = new APP.NewsModel({
title: val.title,
description: val.description,
poster: val.poster
});

self.collection.add(newsModel);
});

// console.log(this.collection);
}

});


view news unit:

APP.NewsUnitView = Backbone.View.extend({

initialize: function(model) {
self = this;

this.model = model.model;
},

className: 'news',

template: _.template($('#newsUnitTpl').html()),

render: function () {
this.$el.html(this.template({
title: this.model.get('title'),
description: this.model.get('description'),
poster: this.model.get('poster')
}));
return this;
},

events: {
'click': function() {
self.openModal();
}
},

openModal: function() {
var newsModalView = new APP.NewsModalView(this.model);
newsModalView.show(555, ['dfsdsdf']);
}

});


view news modal:

APP.NewsModalView = Backbone.View.extend({

initialize: function(model) {
var self = this;

this.model = model;
_block = null;
_win = null;
},

template: _.template($('#newsModalTpl').html()),

render: function () {
$('#modalwindow').html(this.template({
id: this.model.cid,
title: this.model.get('title'),
description: this.model.get('description'),
poster: this.model.get('poster')
}));

return this;
},

initBlock: function() {
var self = this;

var _block = document.getElementById('blockscreen');

if (!_block) {
var parent = document.getElementsByTagName('body')[0],
obj = parent.firstChild;

_block = document.createElement('div');
_block.id = 'blockscreen';
parent.insertBefore(_block, obj);

_block.onclick = function() { self.close() };
}

_block.style.display = 'inline';
},

initWin: function(width, html) {
var self = this;

_win = document.getElementById('modalwindow');

if (!_win) {
var parent = document.getElementsByTagName('body')[0];
var obj = parent.firstChild;
_win = document.createElement('div');
_win.id = 'modalwindow';
_win.style.padding = '0 0 5px 0';
parent.insertBefore(_win, obj);
}

_win.style.width = width + 'px';
_win.style.display = 'inline';

_win.innerHTML = html;

_win.style.left = '50%';
_win.style.top = '10%';

_win.style.marginTop = -(_win.offsetHeight / 2) + 'px';
_win.style.marginLeft = -(width / 2) + 'px';

this.render();

document.getElementById('closeBtn').onclick = function() { self.close() };
},

close: function() {
document.getElementById('blockscreen').style.display = 'none';
document.getElementById('modalwindow').style.display = 'none';
},

show: function(html) {
this.initBlock();
this.initWin(html);
}

});

Answer

The problem is with

initialize: function(model) {   
    self = this; 

    this.model = model.model;
  }

since you haven't declared 'self' here and you have't added 'Use strict' javascript engine is using it by declaring it globally, and it gets overwritten on every assignment.

try changing

events: {
    'click': function() {
      self.openModal();
    }
  }

to

events: {
    'click': function() {
      this.openModal();
    }
  }

I have updated the fiddle.

One more thing do not declare var self = this in every view, whenever callback is called by backbone the context to the function is set properly to the respective view.

Comments