0

In my controller (ExtJS 4.2.1) I have a function where I create a window like this:

refs: [{
        ref: 'holidayView',
        selector: '[xtype=holiday.view]'
    }],
    init: function (application) {
        this.control({
            '[xtype=holiday.view] button#btnPrint': {
                click: me.onPrint
            }
        });
    },
    onPrint: function () {

        var me = this;

        var window = Ext.create('Ext.window.Window', {
            title: 'My Window',
            itemId: 'myWindow',
            width: 300,
            height: 300,
            modal: true,
            layout: fit,
            items: [{
                xtype: 'panel'
            }]
        });

        window.show();

    },
    otherFunction: function () {
        var me = this;
        // here I need to close the window
        // I tried this:

        var window = me.getHolidayView().up('#myWindow'); // but its undefined
        // me.getHolidayView() is accesible

        // I also have tried this:
        var window = me.getHolidayView().down('#myWindow'); // also its undefined

    }

Any clue on how to get the window component so I can close it?

Thanks-

UPDATE:

I tried this and it worked great but now sure if this is the right way:

 var win = Ext.WindowManager.getActive();
            if (win) {
                win.close();
            }
VAAA
  • 14,531
  • 28
  • 130
  • 253

2 Answers2

4

Your error is within the following line:

var window = me.getHolidayView().up('#myWindow');

A window is by default floated an therefore has (by default) not a owner container. That is why you cannot look them up by using up() or down(), because they are not placed within that hierarchy. Below are three variants for accessing windows (or any other views)

Variant A

Using the WindowManager is absolutely fine. In addition you can do it from every part of your app. That is what Managers are for (like the StoreManager)

var win = Ext.WindowManager.getActive();
if (win) {
    win.close();
}

Variant B

But there may be a situation with multiple windows, now the WindowManager can still provide you with all windows but you would need to iterate over them if you not know for sure that the active one is the one you are looking for. At this time the auto getter - or call the refs - becomes handy. First you need to ensure that you have either your own view for your window or any unique identifier. Now you can create ref for your window as you have already done it in your example. Following a example that uses a different selector:

{
    ref: 'customWin',
    selector: 'window[itemId=anystring]'
}

Note that the following selector will look for a window with a property called itemId which is defined like itemId:'anystring'. Also note that a ref can also create the window, if nit not already exist. See the refs docs for more information. Also note the created refs are public, meaning just get the controller instance from anywhere in your app (I suppose you have a appProperty defined) and call the created getter like so

App.appPropertyValue.getController('name').getCustomWin()

Variant C

Last but not least you can create your own getter like @incutonez has done it.

getMyWindow: function() {
  var myWindow = this.myWindow;
  if (!myWindow) {
    myWindow = this.myWindow = Ext.create('Ext.window.Window', {
      title: 'My Window',
      width: 300,
      height: 300,
      modal: true,
      layout: fit,
      items: [{
        xtype: 'panel'
      }]
    });
  }
  return myWindow;
}
sra
  • 23,820
  • 7
  • 55
  • 89
1

I use Ext JS in a slightly different way, so take this with a grain of salt... I don't even touch the refs or init stuff, as that just feels wrong, but I'm keeping it in for this example because I don't know what holidayView is. I would do something like this:

refs: [{
  ref: 'holidayView',
  selector: '[xtype=holiday.view]'
}],
init: function (application) {
  this.control({
    '[xtype=holiday.view] button#btnPrint': {
      click: me.onPrint
    }
  });
},
onPrint: function () {
  var me = this;

  var myWindow = this.getMyWindow();
  if (myWindow) {
    window.show();
  }
},

getMyWindow: function() {
  var myWindow = this.myWindow;
  if (!myWindow) {
    myWindow = this.myWindow = Ext.create('Ext.window.Window', {
      title: 'My Window',
      width: 300,
      height: 300,
      modal: true,
      layout: fit,
      items: [{
        xtype: 'panel'
      }]
    });
  }
  return myWindow;
},

otherFunction: function () {
  var me = this;
  // here I need to close the window
  // I tried this:

  var window = me.getMyWindow(); // but its undefined
}

It feels more like OOP to me... I've got a getter, and I don't have to worry about managing the ID... obviously the private variable myWindow can become a problem, but it feels more right with the getter in place, and I can reuse this window.

incutonez
  • 3,241
  • 9
  • 43
  • 92
  • Sound interesting, the problem there as you said is the variable myWindows that you have to be very careful of not declaring on other controller or part of the app the same variable name isnt it? – VAAA Jul 09 '14 at 02:38
  • what do you think about: var win = Ext.WindowManager.getActive(); if (win) { win.close(); } – VAAA Jul 09 '14 at 02:39
  • Well no... the controller should have its own scope, so using `myWindow` in other classes/controllers should be no problem, as it'll be something completely different or undefined if you haven't set it. – incutonez Jul 09 '14 at 02:39
  • To be honest, I don't like it. `Ext.WindowManager.getActive()` just doesn't jive with me. One main reason is, what if they get rid of WindowManager? Then your code is broken. It also will only get me the active window... what if I have multiple windows open? – incutonez Jul 09 '14 at 02:40
  • You are totally right!! Thanks for the feedback. Will give a few hours to see if there is any other answer and then will Select yours. Thanks a lot – VAAA Jul 09 '14 at 02:44
  • No problem. It's hard to really discern the best design principles with Ext JS, but I think one valuable principle to adopt is to stay away from their convenient, global functions... like `Ext.getCmp`, etc. Ext JS is class based, and therefore, you should try to stick closely to OOP practices. Sorry... didn't want to sound like a preacher. – incutonez Jul 09 '14 at 02:48
  • You are totally right, and this make sense when Sencha updates their framework because some stuff always breaks :) – VAAA Jul 09 '14 at 02:50