<p dir="auto">Is there any way we can get more sugar for events as observables e.g.</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import {Component, View, Directive, Output, EventEmitter, HostListener} from 'angular2/angular2';
import {DOM} from 'angular2/src/core/dom/dom_adapter';
import {ElementRef} from 'angular2/core';


@Directive({
  selector: '[draggable]'
})
export class Draggable {
  mouseup   = new EventEmitter();
  mousemove = new EventEmitter();
  mousedown = new EventEmitter();
  mousedrag;

  @HostListener('mouseup', ['$event'])
  onMouseup(event) {
    this.mouseup.next(event);
  }

  @HostListener('mousedown', ['$event'])
  onMousedown(event) {
    this.mousedown.next(event);
  }

  @HostListener('mousemove', ['$event'])
  onMousemove(event) {
    this.mousemove.next(event);
  }

  constructor(public element: ElementRef) {

    this.element.nativeElement.style.position = 'relative';
    this.element.nativeElement.style.cursor   = 'pointer';

    this.mousedrag = this.mousedown._subject
      .map(event =&gt; {
        event.preventDefault();
        // calculate offsets when mouse down
        return {
          left: event.clientX - this.element.nativeElement.getBoundingClientRect().left,
          top:  event.clientY - this.element.nativeElement.getBoundingClientRect().top
        };
      })
      .flatMap(imageOffset =&gt; {
        return this.mousemove._subject
          .map(pos =&gt; {
            // calculate offsets from mouse down to mouse moves
            return {
              top:  pos.clientY - imageOffset.top,
              left: pos.clientX - imageOffset.left
            };
          })
          .takeUntil(this.mouseup._subject);
      });

  }

  onInit() {
    this.mousedrag.subscribe({
      next: pos =&gt; {
        // Update position
        this.element.nativeElement.style.top  = pos.top  + 'px';
        this.element.nativeElement.style.left = pos.left + 'px';
      }
    });
  }

}

@Component({
  selector: 'app'
})
@View({
  // needed in order to tell Angular's compiler what's in the template
  directives: [ Draggable ],
  styles: [`
    [draggable] {
      -webkit-transform: translate3d(0, 0, 0);
      -moz-transform: translate3d(0, 0, 0);
      -ms-transform: translate3d(0, 0, 0);
      transform: translate3d(0, 0, 0);
      background-image: url(https://cdn.rawgit.com/Reactive-Extensions/rx.angular.js/master/examples/draganddrop/logo.png);
      background-repeat: no-repeat;
      background-position: center;
      background-size: contain;
      height: 200px;
      width: 200px;
      color: #000000;
      border: 1px solid #666666;
      padding: 10px;
    }
  `],
  template: `

  &lt;div draggable&gt;
    Draggable Div
  &lt;/div&gt;

  `
})
export class App {
  constructor() {

  }
}
"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-kos">{</span><span class="pl-smi">Component</span><span class="pl-kos">,</span> <span class="pl-smi">View</span><span class="pl-kos">,</span> <span class="pl-smi">Directive</span><span class="pl-kos">,</span> <span class="pl-smi">Output</span><span class="pl-kos">,</span> <span class="pl-smi">EventEmitter</span><span class="pl-kos">,</span> <span class="pl-smi">HostListener</span><span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'angular2/angular2'</span><span class="pl-kos">;</span>
<span class="pl-k">import</span> <span class="pl-kos">{</span><span class="pl-smi">DOM</span><span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'angular2/src/core/dom/dom_adapter'</span><span class="pl-kos">;</span>
<span class="pl-k">import</span> <span class="pl-kos">{</span><span class="pl-smi">ElementRef</span><span class="pl-kos">}</span> <span class="pl-k">from</span> <span class="pl-s">'angular2/core'</span><span class="pl-kos">;</span>


@<span class="pl-smi">Directive</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
  <span class="pl-c1">selector</span>: <span class="pl-s">'[draggable]'</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span>
<span class="pl-k">export</span> <span class="pl-k">class</span> <span class="pl-smi">Draggable</span> <span class="pl-kos">{</span>
  <span class="pl-c1">mouseup</span>   <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-smi">EventEmitter</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-c1">mousemove</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-smi">EventEmitter</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-c1">mousedown</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-smi">EventEmitter</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-c1">mousedrag</span><span class="pl-kos">;</span>

  @<span class="pl-smi">HostListener</span><span class="pl-kos">(</span><span class="pl-s">'mouseup'</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-s">'$event'</span><span class="pl-kos">]</span><span class="pl-kos">)</span>
  <span class="pl-en">onMouseup</span><span class="pl-kos">(</span><span class="pl-s1">event</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">mouseup</span><span class="pl-kos">.</span><span class="pl-en">next</span><span class="pl-kos">(</span><span class="pl-s1">event</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>

  @<span class="pl-smi">HostListener</span><span class="pl-kos">(</span><span class="pl-s">'mousedown'</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-s">'$event'</span><span class="pl-kos">]</span><span class="pl-kos">)</span>
  <span class="pl-en">onMousedown</span><span class="pl-kos">(</span><span class="pl-s1">event</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">mousedown</span><span class="pl-kos">.</span><span class="pl-en">next</span><span class="pl-kos">(</span><span class="pl-s1">event</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>

  @<span class="pl-smi">HostListener</span><span class="pl-kos">(</span><span class="pl-s">'mousemove'</span><span class="pl-kos">,</span> <span class="pl-kos">[</span><span class="pl-s">'$event'</span><span class="pl-kos">]</span><span class="pl-kos">)</span>
  <span class="pl-en">onMousemove</span><span class="pl-kos">(</span><span class="pl-s1">event</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">mousemove</span><span class="pl-kos">.</span><span class="pl-en">next</span><span class="pl-kos">(</span><span class="pl-s1">event</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>

  <span class="pl-en">constructor</span><span class="pl-kos">(</span><span class="pl-k">public</span> <span class="pl-s1">element</span>: <span class="pl-smi">ElementRef</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>

    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">element</span><span class="pl-kos">.</span><span class="pl-c1">nativeElement</span><span class="pl-kos">.</span><span class="pl-c1">style</span><span class="pl-kos">.</span><span class="pl-c1">position</span> <span class="pl-c1">=</span> <span class="pl-s">'relative'</span><span class="pl-kos">;</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">element</span><span class="pl-kos">.</span><span class="pl-c1">nativeElement</span><span class="pl-kos">.</span><span class="pl-c1">style</span><span class="pl-kos">.</span><span class="pl-c1">cursor</span>   <span class="pl-c1">=</span> <span class="pl-s">'pointer'</span><span class="pl-kos">;</span>

    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">mousedrag</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">mousedown</span><span class="pl-kos">.</span><span class="pl-c1">_subject</span>
      <span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span><span class="pl-s1">event</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
        <span class="pl-s1">event</span><span class="pl-kos">.</span><span class="pl-en">preventDefault</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
        <span class="pl-c">// calculate offsets when mouse down</span>
        <span class="pl-k">return</span> <span class="pl-kos">{</span>
          <span class="pl-c1">left</span>: <span class="pl-s1">event</span><span class="pl-kos">.</span><span class="pl-c1">clientX</span> <span class="pl-c1">-</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">element</span><span class="pl-kos">.</span><span class="pl-c1">nativeElement</span><span class="pl-kos">.</span><span class="pl-en">getBoundingClientRect</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">left</span><span class="pl-kos">,</span>
          <span class="pl-c1">top</span>:  <span class="pl-s1">event</span><span class="pl-kos">.</span><span class="pl-c1">clientY</span> <span class="pl-c1">-</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">element</span><span class="pl-kos">.</span><span class="pl-c1">nativeElement</span><span class="pl-kos">.</span><span class="pl-en">getBoundingClientRect</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">top</span>
        <span class="pl-kos">}</span><span class="pl-kos">;</span>
      <span class="pl-kos">}</span><span class="pl-kos">)</span>
      <span class="pl-kos">.</span><span class="pl-en">flatMap</span><span class="pl-kos">(</span><span class="pl-s1">imageOffset</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
        <span class="pl-k">return</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">mousemove</span><span class="pl-kos">.</span><span class="pl-c1">_subject</span>
          <span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span><span class="pl-s1">pos</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
            <span class="pl-c">// calculate offsets from mouse down to mouse moves</span>
            <span class="pl-k">return</span> <span class="pl-kos">{</span>
              <span class="pl-c1">top</span>:  <span class="pl-s1">pos</span><span class="pl-kos">.</span><span class="pl-c1">clientY</span> <span class="pl-c1">-</span> <span class="pl-s1">imageOffset</span><span class="pl-kos">.</span><span class="pl-c1">top</span><span class="pl-kos">,</span>
              <span class="pl-c1">left</span>: <span class="pl-s1">pos</span><span class="pl-kos">.</span><span class="pl-c1">clientX</span> <span class="pl-c1">-</span> <span class="pl-s1">imageOffset</span><span class="pl-kos">.</span><span class="pl-c1">left</span>
            <span class="pl-kos">}</span><span class="pl-kos">;</span>
          <span class="pl-kos">}</span><span class="pl-kos">)</span>
          <span class="pl-kos">.</span><span class="pl-en">takeUntil</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">mouseup</span><span class="pl-kos">.</span><span class="pl-c1">_subject</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
      <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>

  <span class="pl-kos">}</span>

  <span class="pl-en">onInit</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">mousedrag</span><span class="pl-kos">.</span><span class="pl-en">subscribe</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
      <span class="pl-en">next</span>: <span class="pl-s1">pos</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">{</span>
        <span class="pl-c">// Update position</span>
        <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">element</span><span class="pl-kos">.</span><span class="pl-c1">nativeElement</span><span class="pl-kos">.</span><span class="pl-c1">style</span><span class="pl-kos">.</span><span class="pl-c1">top</span>  <span class="pl-c1">=</span> <span class="pl-s1">pos</span><span class="pl-kos">.</span><span class="pl-c1">top</span>  <span class="pl-c1">+</span> <span class="pl-s">'px'</span><span class="pl-kos">;</span>
        <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">element</span><span class="pl-kos">.</span><span class="pl-c1">nativeElement</span><span class="pl-kos">.</span><span class="pl-c1">style</span><span class="pl-kos">.</span><span class="pl-c1">left</span> <span class="pl-c1">=</span> <span class="pl-s1">pos</span><span class="pl-kos">.</span><span class="pl-c1">left</span> <span class="pl-c1">+</span> <span class="pl-s">'px'</span><span class="pl-kos">;</span>
      <span class="pl-kos">}</span>
    <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>

<span class="pl-kos">}</span>

@<span class="pl-smi">Component</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
  <span class="pl-c1">selector</span>: <span class="pl-s">'app'</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span>
@<span class="pl-smi">View</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
  <span class="pl-c">// needed in order to tell Angular's compiler what's in the template</span>
  <span class="pl-c1">directives</span>: <span class="pl-kos">[</span> <span class="pl-smi">Draggable</span> <span class="pl-kos">]</span><span class="pl-kos">,</span>
  <span class="pl-c1">styles</span>: <span class="pl-kos">[</span><span class="pl-s">`</span>
<span class="pl-s">    [draggable] {</span>
<span class="pl-s">      -webkit-transform: translate3d(0, 0, 0);</span>
<span class="pl-s">      -moz-transform: translate3d(0, 0, 0);</span>
<span class="pl-s">      -ms-transform: translate3d(0, 0, 0);</span>
<span class="pl-s">      transform: translate3d(0, 0, 0);</span>
<span class="pl-s">      background-image: url(https://cdn.rawgit.com/Reactive-Extensions/rx.angular.js/master/examples/draganddrop/logo.png);</span>
<span class="pl-s">      background-repeat: no-repeat;</span>
<span class="pl-s">      background-position: center;</span>
<span class="pl-s">      background-size: contain;</span>
<span class="pl-s">      height: 200px;</span>
<span class="pl-s">      width: 200px;</span>
<span class="pl-s">      color: #000000;</span>
<span class="pl-s">      border: 1px solid #666666;</span>
<span class="pl-s">      padding: 10px;</span>
<span class="pl-s">    }</span>
<span class="pl-s">  `</span><span class="pl-kos">]</span><span class="pl-kos">,</span>
  <span class="pl-c1">template</span>: <span class="pl-s">`</span>
<span class="pl-s"></span>
<span class="pl-s">  &lt;div draggable&gt;</span>
<span class="pl-s">    Draggable Div</span>
<span class="pl-s">  &lt;/div&gt;</span>
<span class="pl-s"></span>
<span class="pl-s">  `</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span>
<span class="pl-k">export</span> <span class="pl-k">class</span> <span class="pl-smi">App</span> <span class="pl-kos">{</span>
  <span class="pl-en">constructor</span><span class="pl-kos">(</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>

  <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto"><code class="notranslate">[sidenote] bonus points if you can understand this madness</code></p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="this.mousedrag = this.mousedown._subject.map(event =&gt; (event.preventDefault(), {
    left: event.clientX - this.element.nativeElement.getBoundingClientRect().left,
    top:  event.clientY - this.element.nativeElement.getBoundingClientRect().top
  })).flatMap(imageOffset =&gt; this.mousemove._subject.map(pos =&gt; ({
    top:  pos.clientY - imageOffset.top,
    left: pos.clientX - imageOffset.left
  })).takeUntil(this.mouseup._subject));"><pre class="notranslate"><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">mousedrag</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">mousedown</span><span class="pl-kos">.</span><span class="pl-c1">_subject</span><span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span><span class="pl-s1">event</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">(</span><span class="pl-s1">event</span><span class="pl-kos">.</span><span class="pl-en">preventDefault</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">,</span> <span class="pl-kos">{</span>
    <span class="pl-c1">left</span>: <span class="pl-s1">event</span><span class="pl-kos">.</span><span class="pl-c1">clientX</span> <span class="pl-c1">-</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">element</span><span class="pl-kos">.</span><span class="pl-c1">nativeElement</span><span class="pl-kos">.</span><span class="pl-en">getBoundingClientRect</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">left</span><span class="pl-kos">,</span>
    <span class="pl-c1">top</span>:  <span class="pl-s1">event</span><span class="pl-kos">.</span><span class="pl-c1">clientY</span> <span class="pl-c1">-</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">element</span><span class="pl-kos">.</span><span class="pl-c1">nativeElement</span><span class="pl-kos">.</span><span class="pl-en">getBoundingClientRect</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-c1">top</span>
  <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">flatMap</span><span class="pl-kos">(</span><span class="pl-s1">imageOffset</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">mousemove</span><span class="pl-kos">.</span><span class="pl-c1">_subject</span><span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span><span class="pl-s1">pos</span> <span class="pl-c1">=&gt;</span> <span class="pl-kos">(</span><span class="pl-kos">{</span>
    <span class="pl-c1">top</span>:  <span class="pl-s1">pos</span><span class="pl-kos">.</span><span class="pl-c1">clientY</span> <span class="pl-c1">-</span> <span class="pl-s1">imageOffset</span><span class="pl-kos">.</span><span class="pl-c1">top</span><span class="pl-kos">,</span>
    <span class="pl-c1">left</span>: <span class="pl-s1">pos</span><span class="pl-kos">.</span><span class="pl-c1">clientX</span> <span class="pl-c1">-</span> <span class="pl-s1">imageOffset</span><span class="pl-kos">.</span><span class="pl-c1">left</span>
  <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">.</span><span class="pl-en">takeUntil</span><span class="pl-kos">(</span><span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">mouseup</span><span class="pl-kos">.</span><span class="pl-c1">_subject</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto"><a href="https://tipe.io?ref=github-comment" rel="nofollow"><img src="https://user-images.githubusercontent.com/1016365/34912701-7edec34c-f89c-11e7-8c89-bed6cef064b5.png" alt="github-tipe-logo" style="max-width: 100%;"></a></p>
<p dir="auto">Not sure this is a good idea, or even possible, but thought I'd throw it out there.</p>
<p dir="auto">In vanilla Rx, if I wanted to listen to a DOM event to do a typeahead or something I'd do something like:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="//get DOM element
const input = document.getElementById('myInput');
//observable of click events
const inputs$ = Rx.Observable.fromEvent(input, 'keyup');
//map changes to requests
const responses$ = inputs$.flatMap(ev =&gt; myHttpService.get(ev.target.value)); 
//subscribe to responses
responses$.subscribe(json =&gt; console.log(json));"><pre class="notranslate"><span class="pl-c">//get DOM element</span>
<span class="pl-k">const</span> <span class="pl-s1">input</span> <span class="pl-c1">=</span> <span class="pl-smi">document</span><span class="pl-kos">.</span><span class="pl-en">getElementById</span><span class="pl-kos">(</span><span class="pl-s">'myInput'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-c">//observable of click events</span>
<span class="pl-k">const</span> <span class="pl-s1">inputs$</span> <span class="pl-c1">=</span> <span class="pl-v">Rx</span><span class="pl-kos">.</span><span class="pl-c1">Observable</span><span class="pl-kos">.</span><span class="pl-en">fromEvent</span><span class="pl-kos">(</span><span class="pl-s1">input</span><span class="pl-kos">,</span> <span class="pl-s">'keyup'</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
<span class="pl-c">//map changes to requests</span>
<span class="pl-k">const</span> <span class="pl-s1">responses$</span> <span class="pl-c1">=</span> <span class="pl-s1">inputs$</span><span class="pl-kos">.</span><span class="pl-en">flatMap</span><span class="pl-kos">(</span><span class="pl-s1">ev</span> <span class="pl-c1">=&gt;</span> <span class="pl-s1">myHttpService</span><span class="pl-kos">.</span><span class="pl-en">get</span><span class="pl-kos">(</span><span class="pl-s1">ev</span><span class="pl-kos">.</span><span class="pl-c1">target</span><span class="pl-kos">.</span><span class="pl-c1">value</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span> 
<span class="pl-c">//subscribe to responses</span>
<span class="pl-s1">responses$</span><span class="pl-kos">.</span><span class="pl-en">subscribe</span><span class="pl-kos">(</span><span class="pl-s1">json</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s1">json</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span></pre></div>
<p dir="auto">In current ng2, if I wanted to do the equivalent, I'd do something like:</p>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="@Component({
  selector: 'my-component'
})
@View({
  template: `
     &lt;div [ng-form-model]=&quot;myForm&quot;&gt;
       &lt;input type=&quot;text&quot; ng-control=&quot;query&quot;&gt;
    &lt;/div&gt;
    &lt;ul&gt;
     &lt;li *ng-for=&quot;#result of results | async&quot;&gt;{{result.text}}&lt;/li&gt;
   &lt;/ul&gt;
`
})
class MyComponent {
  constructor(public http: Http, fb: FormBuilder){
    //create form group
    this.myForm = fb.group({
      query: &quot;&quot;
    });
    //subscribe to value changes, map to responses, bind to view w/ pipe
    this.results = this.myForm.controls.query.valueChanges
      .toRx()
      .flatMap(query =&gt; this.http.get(`/foos?q=${query}`)
      .map(res =&gt; res.json());
  }
}"><pre class="notranslate">@<span class="pl-v">Component</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
  <span class="pl-c1">selector</span>: <span class="pl-s">'my-component'</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span>
@<span class="pl-v">View</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
  <span class="pl-c1">template</span>: <span class="pl-s">`</span>
<span class="pl-s">     &lt;div [ng-form-model]="myForm"&gt;</span>
<span class="pl-s">       &lt;input type="text" ng-control="query"&gt;</span>
<span class="pl-s">    &lt;/div&gt;</span>
<span class="pl-s">    &lt;ul&gt;</span>
<span class="pl-s">     &lt;li *ng-for="#result of results | async"&gt;{{result.text}}&lt;/li&gt;</span>
<span class="pl-s">   &lt;/ul&gt;</span>
<span class="pl-s">`</span>
<span class="pl-kos">}</span><span class="pl-kos">)</span>
<span class="pl-k">class</span> <span class="pl-v">MyComponent</span> <span class="pl-kos">{</span>
  <span class="pl-en">constructor</span><span class="pl-kos">(</span><span class="pl-s1">public</span> <span class="pl-s1">http</span>: <span class="pl-v">Http</span><span class="pl-kos">,</span> <span class="pl-s1">fb</span>: <span class="pl-v">FormBuilder</span><span class="pl-kos">)</span><span class="pl-kos">{</span>
    <span class="pl-c">//create form group</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">myForm</span> <span class="pl-c1">=</span> <span class="pl-s1">fb</span><span class="pl-kos">.</span><span class="pl-en">group</span><span class="pl-kos">(</span><span class="pl-kos">{</span>
      <span class="pl-c1">query</span>: <span class="pl-s">""</span>
    <span class="pl-kos">}</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
    <span class="pl-c">//subscribe to value changes, map to responses, bind to view w/ pipe</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">results</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">myForm</span><span class="pl-kos">.</span><span class="pl-c1">controls</span><span class="pl-kos">.</span><span class="pl-c1">query</span><span class="pl-kos">.</span><span class="pl-c1">valueChanges</span>
      <span class="pl-kos">.</span><span class="pl-en">toRx</span><span class="pl-kos">(</span><span class="pl-kos">)</span>
      <span class="pl-kos">.</span><span class="pl-c1">flatMap</span><span class="pl-kos">(</span><span class="pl-s1">query</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">http</span><span class="pl-kos">.</span><span class="pl-en">get</span><span class="pl-kos">(</span><span class="pl-s">`/foos?q=<span class="pl-s1"><span class="pl-kos">${</span><span class="pl-s1">query</span><span class="pl-kos">}</span></span>`</span><span class="pl-kos">)</span>
      <span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span><span class="pl-s1">res</span> <span class="pl-c1">=&gt;</span> <span class="pl-s1">res</span><span class="pl-kos">.</span><span class="pl-en">json</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">This all works great (or will, once Rx stuff settles).</p>
<p dir="auto">However, if I wanted to do the same sort of thing from an arbitrary event (unrelated to forms, like a mousedrag or button click or whatever), there's not a good way (I can see) to get an Observable from a DOM event, so you have to do something like:</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;button (click)=&quot;makeRequest($event)&quot;&gt;Make Request&lt;/button&gt;"><pre class="notranslate"><span class="pl-kos">&lt;</span><span class="pl-ent">button</span> <span class="pl-c1">(click)</span>="<span class="pl-s">makeRequest($event)</span>"<span class="pl-kos">&gt;</span>Make Request<span class="pl-kos">&lt;/</span><span class="pl-ent">button</span><span class="pl-kos">&gt;</span></pre></div>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="//snip
class MyComponent {
  makeRequest($event){
    this.http.get($event.target.url)
      .map(res =&gt; res.json())
      .subscribe(results =&gt; this.results = results);
  }
}"><pre class="notranslate"><span class="pl-c">//snip</span>
<span class="pl-k">class</span> <span class="pl-v">MyComponent</span> <span class="pl-kos">{</span>
  <span class="pl-en">makeRequest</span><span class="pl-kos">(</span><span class="pl-s1">$event</span><span class="pl-kos">)</span><span class="pl-kos">{</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">http</span><span class="pl-kos">.</span><span class="pl-en">get</span><span class="pl-kos">(</span><span class="pl-s1">$event</span><span class="pl-kos">.</span><span class="pl-c1">target</span><span class="pl-kos">.</span><span class="pl-c1">url</span><span class="pl-kos">)</span>
      <span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span><span class="pl-s1">res</span> <span class="pl-c1">=&gt;</span> <span class="pl-s1">res</span><span class="pl-kos">.</span><span class="pl-en">json</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span>
      <span class="pl-kos">.</span><span class="pl-en">subscribe</span><span class="pl-kos">(</span><span class="pl-s1">results</span> <span class="pl-c1">=&gt;</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">results</span> <span class="pl-c1">=</span> <span class="pl-s1">results</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">which isn't nearly as clean.</p>
<p dir="auto">Proposed idea would be to provide a way to delegate / bind an arbitrary DOM event to a Subject/Observable, so that it could be easily subscribed to and handled reactively.</p>
<p dir="auto"><del>Something like (totally made up syntax here, point being we're binding the click event to the Subject):</del></p>
<p dir="auto">Edit: see <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="105490360" data-permission-text="Title is private" data-url="https://github.com/angular/angular/issues/4062" data-hovercard-type="issue" data-hovercard-url="/angular/angular/issues/4062/hovercard?comment_id=231615401&amp;comment_type=issue_comment" href="https://github.com/angular/angular/issues/4062#issuecomment-231615401">#4062 (comment)</a> for current proposal</p>
<div class="highlight highlight-text-html-basic notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="&lt;button [(click)]=&quot;clicks$&quot;&gt;make request&lt;/button&gt;"><pre class="notranslate"><span class="pl-kos">&lt;</span><span class="pl-ent">button</span> <span class="pl-c1">[(click)]</span>="<span class="pl-s">clicks$</span>"<span class="pl-kos">&gt;</span>make request<span class="pl-kos">&lt;/</span><span class="pl-ent">button</span><span class="pl-kos">&gt;</span></pre></div>
<div class="highlight highlight-source-js notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="class MyComponent {
  clicks$ = new Rx.Subject();
  constructor(){
    this.results = this.clicks$
      .flatMap(ev =&gt; http.get('someurl.json'))
      .map(res =&gt; res.json())
  }
}"><pre class="notranslate"><span class="pl-k">class</span> <span class="pl-v">MyComponent</span> <span class="pl-kos">{</span>
  <span class="pl-c1">clicks$</span> <span class="pl-c1">=</span> <span class="pl-k">new</span> <span class="pl-v">Rx</span><span class="pl-kos">.</span><span class="pl-c1">Subject</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-en">constructor</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">{</span>
    <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">results</span> <span class="pl-c1">=</span> <span class="pl-smi">this</span><span class="pl-kos">.</span><span class="pl-c1">clicks$</span>
      <span class="pl-kos">.</span><span class="pl-en">flatMap</span><span class="pl-kos">(</span><span class="pl-s1">ev</span> <span class="pl-c1">=&gt;</span> <span class="pl-s1">http</span><span class="pl-kos">.</span><span class="pl-en">get</span><span class="pl-kos">(</span><span class="pl-s">'someurl.json'</span><span class="pl-kos">)</span><span class="pl-kos">)</span>
      <span class="pl-kos">.</span><span class="pl-en">map</span><span class="pl-kos">(</span><span class="pl-s1">res</span> <span class="pl-c1">=&gt;</span> <span class="pl-s1">res</span><span class="pl-kos">.</span><span class="pl-en">json</span><span class="pl-kos">(</span><span class="pl-kos">)</span><span class="pl-kos">)</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">I saw <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="104931690" data-permission-text="Title is private" data-url="https://github.com/angular/angular/issues/3992" data-hovercard-type="pull_request" data-hovercard-url="/angular/angular/pull/3992/hovercard" href="https://github.com/angular/angular/pull/3992">#3992</a>, but I believe this is for emitting events "out" from the component, whereas this idea is more for usage within a component.</p>
<p dir="auto">Thoughts?</p>