Tutorial:RelayEvents (Legacy)

This version of our Learning Center is unmaintained.
This article may be out-of-date or contain incorrect information.
Please visit the new Sencha Learning Center for up-to-date material.

Go to the new Sencha Learning Center

From Sencha - Learn

Jump to: navigation, search
Summary: Creating custom events and passing them to other components via RelayEvents
Author: MikeB
Published: 4 March 2009
Ext Version: 2.2.0+
Languages: en.png Englishcn.png Chinese

Contents

Introduction

I've seen a number of users on this site asking about how to have components talk to each other or how to make use of the relayEvents() function.

Well, I too have had similar questions and just completed an application where I've finally gotten the relayEvents() function to work the way I wanted it to.

Now it's not even all that hard, I just had to finally break down and figure out how to do it and simply do it.

So first, a brief explaination of the simple application I put together for this tutorial. My final application is much more complex than this tutorial but I've simplified things down quite a bit while still having something here which other developers might find useful.

I have an application where I have a window containing a two pane border layout. The layout has a left, Navigation panel using a tree component, and a right content panel (which is simply an Ext.Panel component).

When the user clicks on a branch or a node in the tree I want to see something happen in the content panel. But rather than having the tree component know anything about the content panel, I want the tree to fire a custom event which is then intercepted by the window which contains both the tree and the panel. The window, knowing about both the Navigation Tree and the Content Panel will take the information passed up from the event in the Tree Panel and process it to put information in the Content Panel.

So let's first take a look at the HTML code for the application (you can take and drop this entire block of code in the "Examples" directory and it should work perfectly fine).

Code

Web Page

The web page itself is fairly straightforward if you've looked at any of the other examples you'll recognize it, so I won't go into it here other than to point out the three javascript files:

  • wcc.tree.js
  • wcc.app.js
  • relayEvents.js

which will be explained shortly

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  <title>Relay Events</title>
  <link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
 
  <!-- GC -->
  <!-- LIBS -->
  <script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
  <!-- ENDLIBS -->
 
  <script type="text/javascript" src="../../ext-all.js"></script>
 
  <script type="text/javascript" src="wcc.tree.js"></script>
  <script type="text/javascript" src="wcc.app.js"></script>
  <script type="text/javascript" src="relayEvents.js"></script>
 
  <!-- Common Styles for the examples -->
  <link rel="stylesheet" type="text/css" href="../shared/examples.css" />
 
</head>
<body>
  <script type="text/javascript" src="../shared/examples.js">
  </script><!-- EXAMPLES -->
 
  <h1>Ext.relayEvents</h1>
  <button id="theBtn">Run</button>
  <p>The js is not minified so it is readable. See:
    <ul style="margin-left:100px;">
      <li><a href="wcc.tree.js">wcc.tree.js</a></li>
      <li><a href="wcc.app.js">wcc.app.js</a></li>
      <li><a href="relayEvents.js">relayEvents.js</a></li>
    </ul>
  </p>
 
</body>
</html>

Custom TreePanel

The first javascript file (wcc.tree.js) contains the code for my custom extension of a standard TreePanel. Rather than have to pass all the same configuration parameters over and over again for most of my apps which use a TreePanel, I've simply created my own extension which I can use over and over again.

I use a custom treeLoader which is forced to use a "GET" http request and to assign onclick handlers to the nodes which are created.

The onclick handlers will fire the custom events "clickLeaf" or "clickBranch" depending on whether a leaf or branch is clicked.

/**
 *
 * Custom Tree, with my typical defaults, a TreeSorter
 * and custom events to pass on to other components
 */
Ext.ns("wcc");    // extablish a namespace for all my component parts
 
 
wcc.tree = Ext.extend(Ext.tree.TreePanel, {
  initComponent: function() {
    // component configuration code here!
    this.rootID = this.rootID ? this.rootID : Ext.id();
    Ext.apply(this,  {
        // default config params here
      animate:true,
      autoScroll:true,
      enableDD:true,
      containerScroll: true,
        // custom tree loader
      loader: new Ext.tree.TreeLoader( {
        url : this.url,
        requestMethod : "GET",
        createNode : function( attr ) {
            // what type of custom event should we fire?
          var NodeEvent = attr.leaf ? "clickLeaf" : "clickBranch";
 
          attr.listeners = {
            click : function( obj, evt, scope) {
                // fire the custom event
              this.ownerTree.fireEvent(NodeEvent, this, attr, attr.text);
            }
          };
            // Perform default method
          return Ext.tree.TreeLoader.prototype.createNode.call(this, attr);
        }
      }),
 
      root : new Ext.tree.AsyncTreeNode({
        text: this.rootID,
        id : this.rootID,
        expanded : true,
        draggable : false
      })
    });
    wcc.tree.superclass.initComponent.apply(this, arguments);
    new Ext.tree.TreeSorter(this, {folderSort:true});
 
      // Add 2 new events to the tree component which will be fired by clicking on a node
    this.addEvents( 'clickLeaf', 'clickBranch');
  }
});
Ext.reg('wccTree', wcc.tree);

So the only real customization necessary are the following lines:

this.ownerTree.fireEvent(NodeEvent, this, attr, attr.text);

which will cause the tree to fire the desired NodeEvent (based on the node type when it is created).

And:

this.addEvents( 'clickLeaf', 'clickBranch' );

which adds the custom events to the tree extension itself.

Application Class

Ok, now that we have the custom TreePanel which will fire custom events how do we trap those events outside our TreePanel and do something with them?

So let's take a look at the application class defined for this application inside wcc.app.js (I try to encapsulate all my applications within their own classes).

Once again there's nothing really special here, I create my own class in the "wcc" namespace I've created with some private variables and functions for setting up the individual panels of a window.

wcc.app = function() {
  // Private Variables...
  var win;
  var button;
 
  // Private Methods...
  var buildApp = function( cfg ) {
      // set up the common config params for both panels
    var dfltCfgParams = {
      split : true,
      collapsible : true,
      margins : "3 0 3 3",
      cmargins : "3 3 3 3"
    };
 
      // set up the config params for the navigation tree panel
    var treeParams = Ext.apply( {
      region : "west",
      width : 200,
      frame : true,
      title : "Navigation"
    }, cfg );
 
      // create the tree panel
    var tree = new wcc.tree(
      Ext.apply( treeParams, dfltCfgParams )
    );
 
      // create the content panel
    var content = new Ext.Panel(Ext.apply({
      title : "Content",
      region : "center",
      frame : true
    }, dfltCfgParams ));
 
      // create the window with a border layout
      // using the tree and content panels
    win = new Ext.Window({
      title    : 'Layout Window',
      closable : true,
      width    : 600,
      height   : 350,
      plain    : true,
      layout   : 'border',
      items    : [ tree, content ]
    });
 
      // Tell the window to handle the custom 'clickLeaf' and
      // 'clickBranch' events from the tree/navigation panel
    win.relayEvents(tree, ['clickLeaf', 'clickBranch']);
 
      // here's the handlers for the custom TreePanel events
      // nothing fancy for the example but lots more could be done.
    win.on( {
      'clickLeaf' : function (nodeObj, nodeAttr, nodeText) {
        console.log("Window - NodeClick - " + nodeText);
        content.body.update("Hello World... Loading Text from Leaf: " + nodeObj.id);
      },
      'clickBranch' : function(nodeObj, nodeAttr, nodeText) {
        console.log("Window - BranchClick - " + nodeText);
        content.body.update("Hello World... Loading Text from Branch: " + nodeObj.id);
      },
      scope : this
    });
  };
 
 
    // Public Area
  return {
    myTree : {},
    root : {},
 
      // I like to have information about my classes
      // embedded in the class mostly for debugging purposes
      // and documentation, but they're not needed in production
    name : "wcc:App",
    desc : "Generic App Class in private Namespace",
 
    init : function(cfg) {
      this.curFunc = this.name + ".init()";
 
      button = Ext.get("theBtn");
      button.on("click" , function() {
        buildApp( cfg );
        win.show(button);
      });
    }
  };	// End Public Return
}();

Once again the key line of code here is the

win.relayEvents(tree, ['clickLeaf', 'clickBranch']);

which tells our window that it can intercept and process the 'clickLeaf' and 'clickBranch' events passed from the tree component

Final Step

Then, finally there's the code which kicks the whole thing off...

Ext.onReady( function() {
  console.log("App running...");
  wcc.app.init({
    url : "getNodes.php",
    rootID : "examples"  // This is also the folder name to show
  });
}, wcc.app, true);
console.log("App Ready to run...");

Note that I'm making use of the "getNodes.php" from the various other TreePanel examples.

So that's it using custom events and passing them to other components via the relayEvents() method is simple and painless and a GREAT help when you want to have a hierarchical structure for your application code.

Here's a link to the forum thread [1] on this tutorial which also includes all the source code (including the getNodes.php file) which can be unzipped directly into your examples folder.


This page was last modified on 31 March 2009, at 03:41. This page has been accessed 23,684 times.