Route model refresh?


#1

Hello,

I am slowly building up my ember app but I have encountered a problem that I don’t entirely understand. I am either doing it wrong or it’s a bug/design flaw.

This is basically my setup. When I go to my app I have a logged in session user that I store on the top application layer. For the user to go to their profile I have a linkto link in the main menu like this: {{#linkTo profile sessionUser }}Profile{{/linkTo}}. I supply the stored user model to the linkto helper and the link it generates is correct.

Now, if I am viewing another users profile page that uses the same route but with a different model loaded and then go to the menu to view my own profile page the handlebar variables don’t update. If I make the variables bound they update but not if they are unbound. In a way this makes sense but here comes the weird part. If I let say go to /profile/photos and then back to the same route the profile page does refresh to the correct loaded model even with unbound variables. I feel this is very inconsistant. The variables should always reflect the model loaded with the controller. There are many use cases where I do not need bounded variables.

I hope I explained it clearly :slight_smile:

Thanks!


#2

Your code would help.

I’ll make a guess despite only partially understanding what you’re saying. The unbound variables are refreshed when the view is rebuilt.

  1. Some view is built with model
  2. Model is changed doing something, view stays the same
  3. You switch to a different view
  4. Return to the first view, and it’s rebuilt with the updated model (reflecting changes from the second step).

#3

Thanks for your reply! I am sorry if I didn’t describe it clearly. As I am new to ember I am not yet entirely familiar with the inner workings. I am attaching my router code below.

I’ll try to clarify.

  1. Two models are loaded. One is the logged in user and is stored on the top parent layer/route. The second user model is attached to the profile view/route and populates all the variables in the template. The route for this step is profile.index.

  2. I click on a link in the menu that is built with the logged in user model. I can see that ember then transitions into profile.index again but with a different model. Bound values get updated but unbound do not.

  3. I now go to profile.albums and then back to profile.index. The unbound variables are now set to the model I loaded in step 2.

    App.Router.map(function() {
       this.resource('profile', { path: '/:username' }, function() {
    	   this.route('albums');
       });
    });
    
    
    App.ApplicationRoute = Ember.Route.extend({
         model: function() {
    	    return App.User.find('1');
         },
         setupController: function(controller, model) {
    
    	     controller.set('sessionUser', model);
         }
    });
    
    
    App.ProfileRoute = Ember.Route.extend({
         model: function(params) {
    	    return App.User.find(params.username);
        },
        serialize: function(model) {
    	     return { username: model.get('username') };
        },
        renderTemplate: function() {
    	     this.render('profile');
        }
    });
    
    App.ProfileIndexRoute = Ember.Route.extend({
         model: function() {
    	    var user = this.modelFor('profile');
    	    return App.Photo.findUserPhotos(user.id);
         },
         setupController: function(controller, model) {
    	     this.controllerFor('profilePhotos').set('model', model);
        },
        renderTemplate: function() {
    	     this.render('profile.photos')
        }
    });
    
    App.ProfileAlbumsRoute = Ember.Route.extend({
         model: function() {
    	    var user = this.modelFor('profile');
    	    return user;
         }
    });
    

#4

So I believe my problem is that my view isn’t refreshed even though my url has changed. The route is the same but my url is not and therefore I am expecting my view to get refreshed with the correct variables.

Basically if I go to /michael it will load the route profile.index. If I then go to /john I will again transition into profile.index but my view is not updated. Only if I have bound values. If I then go to /john/albums and back to /john my view is finally updated.

Is this the expected behavior? I would assume as my model and url is changed so would the view?


#5

Would really appreciate it if someone with a deeper knowledge of ember could explain what the expected behavior is in this use case. As I am new to a one-page app I realize the thinking is different from a more traditional setup and also the roles of MVC in ember. Do views only get updated when the route changes? As it is right now I need to bound everything which seems a waste on items such as loading a massive amount of photos. Also when I change content I have view logic that needs to update in order to change the photo layout.

Appreciate any help I can get! Thanks!


#6

From my limited understanding I think that you are not actually changing route/state when navigating from /michael to /john, you are only swapping the model and the current state stays the same.

The model/content on the controller changes and by association all the bindings to that model will update. The view is reused rather than torn down and rebuilt which is why unbound values won’t change.


#7

Thanks for your reply!

Yes that is also the conclusion I have come to but since the log says that it transitions into a new route I was expecting it to re-load and the app to be in a new state. For now I will have to force the view to re-render somehow when the model changes.


#8

@Surfer if I’m not mistaken this is the cause of your problem https://github.com/emberjs/ember.js/blob/master/packages/ember-routing/lib/ext/view.js#L19-L42

around rc5 this performance optimization was introduced and it basically prevents ember to rerender a view when only the associated model changes

as you said a possible solution is to observe the model property from the view and call rerender()

alternatively you can just avoid using the unbound helper.


#9

Thank you! That would explain what’s going on in my case.

I will look into how I can rerender a view. Right now I am using the unbound helper as I can’t find an easy way to concatenate the image url’s in the template when bounding my data. Also I assume that loading 100’s of bound images into a view won’t help performance either.


#10

I am trying to figure out how to call the rerender function when the model has changed. I assume I use the observes property but not sure what I should observe and where I should put it. Is it possible to observe a model property in the view or must I do this from the controller?


#11

You can easily do in the view, although I’m not entirely sure that it’s a good idea

myObserver: function(){
  //your code
  this.rerender();
}.observes('context.model')

this is just a quick-n-dirty solution, others might have better suggestions


#12

Thanks I will try this.


#13

This topic was automatically closed after 7 days. New replies are no longer allowed.