Image tag flickers then disappears - backbonejs - node.js

I am experiencing a strange behavior with backbone view,
On my view template, the image tag flickers and then disappears immediately when the view is rendered, no image is then displayed
this is my first backbonejs/nodejs application and I have spent quite some time trying to debug this,I hope I am clear enough, thanks.
Here is my code:
//The Backbone view
define(['text!templates/profile.html'],function(profileTemplate){
var profileView=Backbone.View.extend({
el:$('#content'),
initialize:function(){
this.model.bind('change',this.render,this);
},
viewTemplate: _.template(profileTemplate),
render:function(){
this.model.fetch();
this.$el.html(this.viewTemplate(this.model.toJSON()));
}
});
return profileView;
});
//HTML TEMPLATE (profile.html)
<img src="uploads/<%= photo%>" alt="image" />
//SCHEMA
var AccountSchema=new mongoose.Schema({
email:{type:String,unique:true},
password:{type:String},
name:{
first:{type:String},
last:{type:String},
},
photo:{type:String},
});
Directory Structure
/ParentDirectory
/Public
/templates
profile.html //this is the template being rendered
/uploads //contains images
//ROUTER
define(['views/profile'],function(ProfileView){
var router=Backbone.Router.extend({
currentView:null,
routes:{
"profile/:id":"profile"
},
//Calls render method on views
changeView:function(view){
if(null !=this.currentView){
this.currentView.undelegateEvents();
}
this.currentView=view;
this.currentView.render();
},
profile:function(id){
var model=new Account({id:id});
this.changeView(new ProfileView({model:model}));
},
return new router();
});

There is some issue here on the code:
initialize:function(){
this.model.bind('change',this.render,this);
},
render:function(){
this.model.fetch();
this.$el.html(this.viewTemplate(this.model.toJSON()));
}
You are fetching the model inside render function (which just feels wrong) the model get updated and trigger a change event that calls render which starts the same loop all over again.

Related

New to Sails.js how can I route to a view without including the layout.ejs?

New to Sails.js I've read over the docs but I don't see a way to NOT include the layout.ejs located in /views/.
I'm trying to implement Angular into my app and when I go
$routeProvider.when('/',{
controller: 'HomeController',
templateUrl: '/home'
})
So then in my routes I expect to be able to do:
'GET /home': { view: 'angular/home.ejs' }
But what happens is it loads home.ejs but also injects layout.ejs so it becomes an endless loop of injecting layout.ejs loading angular scripts from layout, then trying to load home.ejs which loads layout.ejs so on so forth
So how can I do this?
I know I can put views in /asset/angular/home.html but I would like to have .ejs so that I can render a different view (e.g. user is not logged in) or something.
Any information on how I can render views without injecting layout.ejs would be great, thanks!
Update:
So by doing this:
'GET /home': {
view: 'home',
locals: {
layout: false
}
}
it makes it work, I don't know if there is a global way so I don't have to flag layout: false for each one
To disable layouts globally, you can put layout : false under /config/view.js.
To disable layout individually, leave /config/view.js alone and do something like this in your routes:
'GET /home': {
view: 'home',
locals: {
layout: false
}
}

Instafeed pagination and limit not working for chosen tag, yet same code works for other tags

The following Instafeed code shows not 5 but 6 images, and the #load-more button is hidden, indicating hasNext() is false:
var tagged_cofiwear = new Instafeed({
target: 'instagram-tagged',
get: 'tagged',
tagName: 'cofiwear',
clientId: '8852afa8788546a199c37543b77b043c',
sortBy: 'most-recent',
limit: 5,
template: '<a target="_blank" href="{{link}}"><img src="{{image}}" /></a>',
after: function() {
if (!this.hasNext()) {
$('#load-more').hide();
}
}
});
tagged_cofiwear.run();
$('#load-more').on('click', function() {
tagged_cofiwear.next();
});
To try and troubleshoot, I found a jsfiddle with Instafeed pagination that works (http://jsfiddle.net/unuLyzx0/107/) and edited tagName: 'justanotherinvegas' to be tagName: 'cofiwear'.
Here is the result, which also shows the wrong number and the load more button doesn't work :(
http://jsfiddle.net/unuLyzx0/108/
Any tips?
Thanks!
In case it helps anyone else:
Turns out I needed to add the userId and accessToken for the user cofiwear, which happens to be the tag we want from all users.

Instafeed and Masonry

I have this code below where I am trying to use Instafeed and Masonry together. Everything works fine until I click the "Load more" button. Then the Masonry layout breaks. It's probably because something is loading before the other or vice versa. I'm new to this so all help would be greatly appreciated.
I got the tip to use imagesLoaded instead of window.load and also to use appended method. But I don't understand how to incorporate that in to my code.
My code is in a script.js doc and outputs in the footer of the page after instafeed.js and masonry.
$(function () {
var loadButton = document.getElementById('load-more');
if(loadButton !== null) {
var userFeed = new Instafeed({
get: 'user',
userId: xxxxxxxxx,
accessToken: 'xxxxxxxxx',
limit: 6,
resolution: 'standard_resolution',
template: '<div class="col30 grid image-top-fill instapic"><img src="{{image}}" alt="Instagram" /> <p class="nomargin">{{caption}}</p></div>',
after: function() {
if (!this.hasNext()) {
loadButton.setAttribute('disabled', 'disabled');
Masonry.start();
}
}
});
loadButton.addEventListener('click', function() {
userFeed.next();
});
userFeed.run();
}
});
$(window).load(function(){
var container = document.querySelector('#instafeed');
var msnry = new Masonry( container, {
itemSelector : '.instapic',
isAnimated : true,
isFitWidth : false
});
});
Thanks in advance for your help! Let me know if there is anything more you need from me.
Cheers / Jeppe
You're correct in that Masonry is trying to work with elements before they're loaded. You can put .masonry('appended', $items) in the after event of Instafeed. Instafeed's developer posted this fix:
https://github.com/stevenschobert/instafeed.js/issues/118#issuecomment-44438003

Marionette, how to change view's template on fly

I'm doing a single page webApp with Marionette and RequireJs, basically it is a Layout view nested with a lots of ItemView and compositeView. I want the page change to a new design by one click, so I want to ask a best practice about changing the view's template.
say, I got my view like this, and its templates are included by requirejs's text plugin:
define([
'text!templates/designNo1/template.html'
], function(template) {
var MyView = Backbone.Marionette.ItemView.extend({
/*Template*/
template: template,
initialize: function() {
......
},
onRender: function() {
......
}
});
return SkillView;
});
every view and theirs subviews are defined like this. and their templates located in "template/designNo1" folder. now I got a set of new design located in "template/designNo2", and I want apply it to the page, but I found there is no chance to do this, because the views are already loaded by RequireJs and the template's path are hard-coded. of course, I can override the view's template when create the view's instance, but if I do so, I must load all the new design in the upper-module which create the instance, that looks bad, and the new design are keep coming, it gonna be a mess soon.
so, any advice?
From what I can tell, it sounds like you are wanting to change the template on a view depending on different circumstances. Marionette's ItemView has a getTemplate() function that is called when rendering it. You can specify a function that determines which template to render from there.
Another approach might be to simply change the template of the view and re-render it. You could do that on a click event easily:
HTML
<div class="content"></div>
<button class="btn">Change Template</button>
Javascript
var template1 = '<div>Template 1</div>';
var template2 = '<div>Template 2</div>';
var ItemView = Backbone.Marionette.ItemView.extend({
template: template1
});
var itemView = new ItemView({ el: '.content' });
itemView.render();
$('.btn').click(function(e) {
e.preventDefault();
itemView.template = template2;
itemView.render();
});

Send multiple variables through render with Express

Maybe a stupid question but, is it possible to send multiple variables through res.render() in Express ?
Because, when I do
res.render('index', { title: 'Express', name: 'Arnaud' });
I've all this pretty error telling me name is not defined.
In this view
extends layout
block content
h1 Salut #{name}
p Welcome to #{title}
Any idea ?
In route:
res.render("index", { data: { title: "Express", name: "Arnaud" } })
In view:
<%= data.title %>
<%= data.name %>
I also got this problem for a long time and found a workaround: to pass a variable you just should do
res.locals.title = "Express";
res.locals.name = "Arnaud"
res.render("index");
The both variables Express and Arnaud will be given to the EJS context
Weird thing is weird : I regenerated a new Express project and everything is fine...

Resources