title: Adding generic event listener with specific callback
body: <p>In an Aurelia viewmodel component, I have the following JQuery code that works to capture <kbd>Ctrl</kbd>+<kbd>S</kbd> or <kbd>Ctrl</kbd>+<kbd>Enter</kbd> while a modal is visible and call the save function:</p>
  <pre><code>$(window).bind('keydown', function(event) {
    if (event.ctrlKey || event.metaKey) { // Ctrl + ___
      if ((event.which == 83) || (event.which == 115) || (event.which == 10) || (event.which == 13)) {  // Ctrl+Enter or Ctrl+S
        // Save button
        event.preventDefault();
        if ($(self.edit_calendar).is(':visible')) {
          self.saveCalendar();
        }
      }
    }
  });
  </code></pre>
  <p>However, I foresee adding a similar function to 40+ viewmodels, and that doesn't seem very DRY and adds some ugly code to each of my viewmodels.  I would like to create a generic addEventListener function in a singleton class to easily call from each of my views.  Here's what I have in mind:</p>
  <pre><code>addListenerSave(visible, callback) {
    // Add an event listener to redirect keyboard shortcuts to specific actions
    console.log(&quot;addListenerSave()&quot;);
    $(window).bind('keydown', function(event) {
      if (event.ctrlKey || event.metaKey) { // Ctrl + ___
        if ((event.which == 83) || (event.which == 115) || (event.which == 10) || (event.which == 13)) {  // Ctrl+Enter or Ctrl+S
          // Save button
          event.preventDefault();
          if ($(visible).is(':visible')) {
            console.log(&quot;Keyboard shortcut: Save&quot;);
            callback();
          }
        }
      }
    });
  }
  </code></pre>
  <p>Then, in my individual components, I should only need the following code on instantiation (in the <code>attached()</code> component life cycle):</p>
  <pre><code>this.config.addListenerSave(this.edit_calendar, this.saveCalendar);
  </code></pre>
  <p>However, this does not work.  <code>saveCalendar()</code> is called but maybe from another scope/context, so I get an error inside <code>saveCalendar</code> that says:</p>
  <blockquote>
  <p>&quot;Cannot read property 'selectedId' of undefined&quot;.</p>
  </blockquote>
  <p>This is referring to the <code>saveCalendar()</code> code <code>if (this.selectedId)...</code>.  What am I doing wrong?</p>
  <p>Finally, should I also be removing this event listener when my Aurelia component is detached?  How?</p>
  <p>One alternate idea I had was to use Aurelia's <code>eventAggregator</code> to create a global event listener that always is listening for <kbd>Ctrl</kbd>+<kbd>S</kbd> or <kbd>Ctrl</kbd>+<kbd>Enter</kbd> and then publishing a message that can be subscribed in each component.</p>