title: Prevent Rendering (hide and/or disable) of a Component at construction time
body: <p>Background: Our app is always packed as a whole but through the users access some serverside actions may be restricted. We know which actions are allowed the time the app starts. We now want to hide all the views (panels, buttons, etc) from the user to which he lacks the access to.</p>
  
  <p>For that we have written a plugin which can be applied to any Component. But here comes the problems:</p>
  
  <p>Here is what we try to run against the plugin host:</p>
  
  <pre><code>if (cmp['setVisible']) cmp.setVisible(false); else cmp.hidden = true;
  if (cmp['disable']) cmp.disable(); else cmp.disabled = true;
  cmp.on('beforerender', function() { return false; })
  </code></pre>
  
  <p>First we thought the earlier we do this the better. So we tried to run it at construction time of the plugin. But that was not possible because the listeners (of the host) seems to be not ready yet (the component tries to fire the hide event). So we moved it into the <code>init</code> method of the plugin which does not throw a error but just worked partly. Only the <code>beforerender</code> event got really applied but it only aborted the rendering of the child. so we ended up with a broken looking component (the borders are there and the content not). <s>If we commented the event registration out the host stayed untouched. We also tested the use of only the <code>hidden:true</code> and <code>disabled:true</code> with no luck.</s></p>
  
  <p>So how can we <strong>prevent rendering</strong> of component in the correct way?</p>
  
  <p><em>Edit:</em></p>
  
  <p>The component should be flagged as disabled and hidden because we cannot prevent the creation of the component. The snipped I got from my colleague was wrong so the call of <code>setVisible(false)</code> worked, we guess <code>disable()</code> also. But the component get stilled rendered and we seem not really able to veto this without ending up with a half rendered component. </p>
  
  <p><strong>Answer by @AlexTokarev</strong></p>
  
  <p>I tried what @AlexTokarev suggested. For that I added the following lines into the Plugin-Constructor</p>
  
  <pre><code>cmp.hidden = true;
  cmp.autoShow = false; // I know this may do nothing for non floating but I added it anyway
  cmp.autoRender = true;
  </code></pre>
  
  <p>Based on debugging I know that the settings get applied really early (at the <a href="http://docs.sencha.com/extjs/4.2.2/source/AbstractComponent.html#Ext-AbstractComponent-method-constructor" rel="noreferrer">Ext.AbstractComponent.constructor</a>), but I still ending up with a hidden and rendered component.</p>
  
  <p><img src="https://i.stack.imgur.com/6rtDe.png" alt="enter image description here"></p>
  
  <p><strong>Comment by @sbgoran</strong></p>
  
  <p>In one Testcase we use a column-layout in which all containers extend from the same class. As soon as I add our plugin (with the beforerender event returning false configuration) to one of this extending containers (the plugin is directly added to class definition (as ptype)) all containers within this columns look broken (only borders are rendered and in the content a small grey box in the upper left corner.). So the aborted rendering affect all child items of the column when only one child item get the rendering canceled.</p>
  
  <p>**Sample Code **</p>
  
  <p>First I want to note that we are looking for a way to do this in general cause as far as we know the rendering in ExtJS is one thing. I can ask to setup a demo but I think this will not be that easy because we are using the <code>Ext.app.portal.Panel</code> for the failing example. but the plugin should work for any sort of Component. First I will add some demo code:</p>
  
  <p>We have a view which is placed into a Viwport with border layout</p>
  
  <pre><code>Ext.define('MVC.view.Application',{
      extend:'Ext.tab.Panel',
      alias:'widget.appview',
      region: 'center',
      activeTab: 1
  });
  </code></pre>
  
  <p>Within the Controller we fill this</p>
  
  <pre><code>var portal = this.portalRef = Ext.widget('portalpanel', {
      title: 'Employee',
      portalCols: 2
  });
  portal.addPortlet(0,['employee','employee2','employee3']);
  portal.addPortlet(1,['employee4','employee5']);
  app.appviewmain.add(portal);
  </code></pre>
  
  <p>Here is the portal panel</p>
  
  <pre><code>Ext.define('MVC.app.portal.PortalPanel', {
      extend: 'Ext.panel.Panel',
      alias: 'widget.portalpanel',
  
      requires: [
          'Ext.layout.container.Column',
          'Ext.app.portal.PortalDropZone',
          'Ext.app.portal.PortalColumn'
      ],
  
      portalCols: 2,
  
      portalColCfg: {
          defaults: {
              closable: false,
              draggable: false,
              collapsible: false,
              header: false,
              bodyStyle: {
                  background: '#fff',
                  padding: '10px'
              }
          },
          items: []
      },
  
      addPortlet: function(idx, portlets) {
          if (idx &gt; this.portalCols || idx &lt; 0)
              return;
          var portalCol = this.items.getAt(idx);
          function insertPortlet(portlet) {
              if (Ext.isString(portlet)) {
                  portlet = { xtype: portlet };
              }
              portalCol.add(portlet);
          };
  
          if (Ext.isArray(portlets)) {
              var len = portlets.length,
                  i = 0;
              for(;i&lt;len;i++) {
                  insertPortlet(portlets[i]);
              }
          }  else  {
              insertPortlet(portlets);
          }
  
      },
  
      initPortal: function() {
          var cfg = this.portalColCfg,
              i = 0,
              cols = [];
          for (;i&lt;this.portalCols;i++) {
              cols.push(Ext.clone(cfg));
          }
          this.items = cols;
      },
  
      cls: 'x-portal',
      bodyCls: 'x-portal-body',
      defaultType: 'portalcolumn',
      autoScroll: true,
  
      manageHeight: false,
  
      initComponent : function() {
          var me = this;
          // init only if nothing is defined
          if (!me.items)
              me.initPortal();
  
          // Implement a Container beforeLayout call from the layout to this Container
          me.layout = {
              type : 'column'
          };
          me.callParent();
  
          me.addEvents({
              validatedrop: true,
              beforedragover: true,
              dragover: true,
              beforedrop: true,
              drop: true
          });
      },
  
      // Set columnWidth, and set first and last column classes to allow exact CSS targeting.
      beforeLayout: function() {
          var items = this.layout.getLayoutItems(),
              len = items.length,
              firstAndLast = ['x-portal-column-first', 'x-portal-column-last'],
              i, item, last;
  
          for (i = 0; i &lt; len; i++) {
              item = items[i];
              item.columnWidth = 1 / len;
              last = (i == len-1);
  
              if (!i) { // if (first)
                  if (last) {
                      item.addCls(firstAndLast);
                  } else {
                      item.addCls('x-portal-column-first');
                      item.removeCls('x-portal-column-last');
                  }
              } else if (last) {
                  item.addCls('x-portal-column-last');
                  item.removeCls('x-portal-column-first');
              } else {
                  item.removeCls(firstAndLast);
              }
          }
  
          return this.callParent(arguments);
      },
  
      // private
      initEvents : function(){
          this.callParent();
          this.dd = Ext.create('Ext.app.portal.PortalDropZone', this, this.dropConfig);
      },
  
      // private
      beforeDestroy : function() {
          if (this.dd) {
              this.dd.unreg();
          }
          this.callParent();
      }
  });
  </code></pre>
  
  <p>And here is the Portlet</p>
  
  <pre><code>Ext.define('Ext.app.portal.Portlet', {
      extend: 'Ext.panel.Panel',
      alias: 'widget.portlet',
  
      layout: 'fit',
      anchor: '100%',
      frame: true,
      closable: true,
      collapsible: true,
      animCollapse: true,
      draggable: {
          moveOnDrag: false    
      },
      cls: 'x-portlet',
  
      initComponent : function() {
          this.callParent();
      },
  
      // Override Panel's default doClose to provide a custom fade out effect
      // when a portlet is removed from the portal
      doClose: function() {
          if (!this.closing) {
              this.closing = true;
              this.el.animate({
                  opacity: 0,
                  callback: function(){
                      var closeAction = this.closeAction;
                      this.closing = false;
                      this.fireEvent('close', this);
                      this[closeAction]();
                      if (closeAction == 'hide') {
                          this.el.setOpacity(1);
                      }
                  },
                  scope: this
              });
          }
      }
  });
  </code></pre>
  
  <p>Here is a sample view</p>
  
  <pre><code>Ext.define('MVC.view.employee.Employee',{
      extend:'Ext.app.portal.Portlet',
      alias:'widget.employee',
      plugins: [{ptype: 'directbound', accessRoute: 'Employee.Read'}],
      items: [
          /*A form with some fields*/
      ]
  });
  </code></pre>
  
  <p>Here's the plugin</p>
  
  <pre><code>Ext.define('MVC.direct.plugins.DirectBound',{
      extend: 'Ext.AbstractPlugin',
      alternateClassName: ['MVC.direct.DirectBound'],
      alias: 'plugin.directbound',
  
      /**
       * @cfg {int} blockMode Indicates the way in which the Component gets blocked
       * options
       * 0 hide and disable
       * 1 disable
       */
      blockMode: 1,
  
      constructor: function(config) {
          var me = this,
              cmp = config['cmp'], 
              route;
          me.parseRoute(route);
  
          // check for access
          if (!me.checkAccess()) {
              if (me.blockMode === 0) {
                  cmp.hidden = true;
                  cmp.autoShow = false;
                  cmp.autoRender = true;
              }
              me.diabled = true;
          }
  
          me.callParent(arguments);
      }
  
      /* some more methods */
  });
  </code></pre>
  
  <p>Here's the column Layout</p>
  
  <p>Ext.define('MVC.app.portal.PortalColumn', {
      extend: 'Ext.container.Container',
      alias: 'widget.portalcolumn',</p>
  
  <pre><code>requires: [
      'Ext.layout.container.Anchor',
      'MVC.app.portal.Portlet'
  ],
  
  layout: 'anchor',
  defaultType: 'portlet',
  cls: 'x-portal-column'
  
  // This is a class so that it could be easily extended
  // if necessary to provide additional behavior.
  </code></pre>
  
  <p>});</p>