Mr. Polywhirl
Mr. Polywhirl

Reputation: 48600

Ext.Component: Template's afterrender fails to access renderSelectors

Below, you will find two examples using the template-render pattern. Example A does not work correctly. The value cmp.helloLiEl is undefined in the listener function. The afterrender callback does not know about the renderSelectors.

In Example B, the afterrender is assigned an inline function to attach a listener to the template list item. I thought that supplying the function with the scope would suffice, but this did not work as expected.

How can I get Example A's onRender listener to access the renderSelectors?

Example A

Ext.onReady(function() {
  Ext.define('Exmple.component.Hello', {
    extend: 'Ext.Component',
    title: 'Hello Test',
    renderTpl: [
      '<ul>',
      '<li class="lang" id="helloSelector-li">Hello {name}!</li>',
      '</ul>'
    ],
    renderData: {
      name: 'Joe'
    },
    renderSelectors: {
      helloLiEl: '#helloSelector-li'
    },
    listeners: {
      afterrender: {
        fn : this.onRender,
        scope : this
      }
    },
    onRender: function(cmp) {
      console.log(cmp.helloLiEl);
      cmp.mon(cmp.helloLiEl, 'click', function() {
        alert('Hello again...');
      });
    }
  });

  Ext.create('Exmple.component.Hello', {
    renderTo: Ext.getBody(),
    renderData: {
      name: 'Bob'
    }
  });
});
#helloSelector-li {
  background-color: yellow;
  width: 35px;
  height: 30px;
}
<link href="http://cdn.sencha.io/ext-4.1.1-gpl/resources/css/ext-all.css" rel="stylesheet" />
<script src="http://cdn.sencha.io/ext-4.1.1-gpl/ext-all.js"></script>

Example B

Ext.onReady(function() {
  Ext.define('Exmple.component.Hello', {
    extend: 'Ext.Component',
    title: 'Hello Test',
    renderTpl: [
      '<ul>',
        '<li class="lang" id="helloSelector-li">Hello {name}!</li>',
      '</ul>'
    ],
    renderData: {
      name: 'Joe'
    },
    renderSelectors: {
      helloLiEl: '#helloSelector-li'
    },
    listeners: {
      afterrender: function(cmp) {
        console.log(cmp.helloLiEl);
        cmp.mon(cmp.helloLiEl, 'click', function() {
          alert('Hello again...');
        });
      }
    }
  });

  Ext.create('Exmple.component.Hello', {
    renderTo: Ext.getBody(),
    renderData: {
      name: 'Bob'
    }
  });
});
#helloSelector-li {
  background-color: yellow;
  width: 35px;
  height: 30px;
}
<link href="http://cdn.sencha.io/ext-4.1.1-gpl/resources/css/ext-all.css" rel="stylesheet" />
<script src="http://cdn.sencha.io/ext-4.1.1-gpl/ext-all.js"></script>

Upvotes: 2

Views: 279

Answers (1)

Rob Schmuecker
Rob Schmuecker

Reputation: 8954

The issue here is your scope.

Also the onRender function is overriding the method of the same name which it inherits (http://docs.sencha.com/extjs/4.1.3/#!/api/Ext.util.Renderable-method-onRender) so hence I have changed the function name to myTest

Ext.onReady(function() {
    Ext.define('Exmple.component.Hello', {
        extend: 'Ext.Component',
        title: 'Hello Test',
        renderTpl: ['<ul>', '<li class="lang" id="helloSelector-li">Hello {name}!</li>', '</ul>'],
        renderData: {
            name: 'Joe'
        },
        renderSelectors: {
            helloLiEl: '#helloSelector-li'
        },

        initComponent: function() {
            me = this;
            me.listeners = {
                afterrender: {
                    fn: this.myTest,
                    scope: this
                }
            }
            this.callParent();
        },
        myTest: function(cmp) {
            cmp.mon(cmp.helloLiEl, 'click', function() {
                alert('Hello again...');
            });
        }
    });

    Ext.create('Exmple.component.Hello', {
        renderTo: Ext.getBody(),
        renderData: {
            name: 'Bob'
        }
    });
});

Have a look at the answer added here https://stackoverflow.com/a/23806475

Demo: https://fiddle.sencha.com/#fiddle/gqj

Upvotes: 1

Related Questions