1

I'm in the middle of updating my current application to 1.0pre from 0.9.8 and I'm experimenting something I can't understand very well.

One of my templates has a containerview bound to a property:

...
{{view Ember.ContainerView currentViewBinding="oTabPanelFrame"}}
...

And then I changed the container's view by code doing something like this (code executed by an observer):

...
if (sender[key])
    this.set('oTabPanelFrame', sender.get('oFrameView'));
...

Since 1.0pre this works only one time, the second time it tries to set the view, its state changed to 'destroyed' (in 0.9.8 was always 'preRender') and then it's not shown anymore.

So, this is what happens:

  1. User clicks on an UI and it shows view A properly.
  2. User clicks on other UI item and it shows view B properly as well.
  3. User clicks on first UI item and it tries to show view A, but it doesn't. After diving into the view properties, I realized its state changed to 'destroyed'.

Is this a normal behavior?I've checked the 1.0pre changelog and different posts related to view states, but I can't see anything similar.

Thanks in advance!

P.S.: I think code is not relevant here, if you want me to publish more code let me know.

RAmPE
  • 53
  • 3

1 Answers1

0

Well, I don't know what exactly appends between 0.9.8 and 1.0-pre, but I think some work has been done in order to avoid memory leaks. Then as you said, it seems that the views are destroyed when removed from the containerView. The solution I've found is to create the view each time you need it. I think this is not the optimal solution. I will try do do it better, especially by using the childViews property of the Ember.ContainerView.

Here is the implementation very close to yours:

Test = Ember.Application.create();

Test.TabPanel = Ember.View.extend({
  templateName: 'tabpanel',
  tagName: 'span',

  init: function() {
    this._super();
    this.set('oTabPanelFrame', Ember.View.create());
  },
  click1: function(event) {
    event.context.set('oTabPanelFrame', event.context.get('view1').create());
  },
  click2: function(event) {
    event.context.set('oTabPanelFrame', event.context.get('view2').create());
  },

  view1: Ember.View.extend({
    defaultTemplate: Ember.Handlebars.compile("View1's contents")
  }),

  view2: Ember.View.extend({
    defaultTemplate: Ember.Handlebars.compile("View2's contents")
  }),
});

var oMyPanel = Test.TabPanel.create();
oMyPanel.appendTo('#content');​

UPDATE

Since this does not work for you, with the 1.0 version, I think the preferred way to implement this is to use the outlets. Here, there is a great example of how it's implemented: emberjs - how to mark active menu item using router infrastructure

I've modified the fiddle to show you how to keep the state when switching views. In fact, when the view are 'connected', they are also instanciated each time. But the state should be persisted in the controllers or the models.

Here is the fiddle: http://jsfiddle.net/Sly7/z8ssG/11/

Community
  • 1
  • 1
sly7_7
  • 11,961
  • 3
  • 40
  • 54
  • I was thinking about this solution either, but it's not good for my project because my views keep state. I mean, when view1 is shown, the user is able to fill some fields and then change to view2 to look for something. When he/she gets what he/she needs, he/she goes back to view1 to continue filling data, so this approach doens't work unfortunatelly. _Any other idea?_ – RAmPE Aug 15 '12 at 10:04
  • After reading and testing a lot, I've decided the best solution for my project is to create views every time I click on a button as you suggested. In order to keep state I've created some objects storing what users type. When a view is going to be shown, it picks data up from its 'linked' object (in fact they're working as controllers). Because I'm working on a legacy application, I can't use the router thing (at least, I don't know how to do it). For future works I'll have a look to the router system in order to do things more EmberJS style :) @sly7_7 thx very much for ur time & ur help. – RAmPE Aug 16 '12 at 19:11