title: Binding not updating when component property changed in callback
body: <p>I'm creating a Chrome extension with Angular to render a pop-up window.  The view binding is not updating when a callback comes from the Chrome API and a property used in the view binding is altered as of a result of that callback.  Adding additional complication, the callback isn't called directly but wrapped in an Observable.</p>
  <p>If I call <code>ChangeDetectorRef.detectChanges()</code> then the view is updating appropriately.  I tried using NgZone but I may be using it wrong - it has no effect if I include it or exclude it from the method that creates my observable.</p>
  <h3>Relevant Component Code</h3>
  <pre class="lang-ts prettyprint-override"><code>ngOnInit() {
    this.port = chrome.runtime.connect({ name: 'PopupToBackground' });
    // ChromeUtil is an injected service wrapping chrome API calls.
    this.chromeUtil.portOnMessage$(this.port).pipe(
      tap((x: string) =&gt; {
        // text is the bound property
        this.text = x || 'no data';
        // Uncomment line below and everything works.
        //this.cd.detectChanges();
      })
    ).subscribe();
  }
  </code></pre>
  <h3>Relevant ChromeUtil Code</h3>
  <pre class="lang-ts prettyprint-override"><code>@Injectable({ providedIn: 'root' })
  export class ChromeUtil {
    constructor(private zone: NgZone) { }
  
    portOnMessage$(port: chrome.runtime.Port) {
      return new Observable&lt;any&gt;(subscriber =&gt; {
        return this.zone.run(() =&gt; {
          const listener = (msg: any) =&gt; subscriber.next(msg);
          port.onMessage.addListener(listener);
          return { 
            unsubscribe() { 
              port.onMessage.removeListener(listener); 
            } 
          };
        });
      });
    }
  }
  </code></pre>