Skip to content

Commit

Permalink
Merge pull request #12382 from Marklb/marklb/setprops-in-ngzone
Browse files Browse the repository at this point in the history
Angular: Run setProps in the NgZone
  • Loading branch information
shilman committed Dec 1, 2020
2 parents 0e56733 + b776663 commit 0e7f50f
Showing 1 changed file with 22 additions and 5 deletions.
27 changes: 22 additions & 5 deletions app/angular/src/client/preview/angular/helpers.ts
@@ -1,10 +1,10 @@
// @ts-ignore
import { document } from 'global';
import { enableProdMode, NgModule, Component, NgModuleRef, Type } from '@angular/core';
import { enableProdMode, NgModule, Component, NgModuleRef, Type, NgZone } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { BrowserModule } from '@angular/platform-browser';
import { ReplaySubject } from 'rxjs';
import { Observable, ReplaySubject, Subscriber } from 'rxjs';
import { StoryFn } from '@storybook/addons';
import { AppComponent } from './components/app.component';
import { STORY } from './app.token';
Expand All @@ -18,13 +18,27 @@ declare global {

let platform: any = null;
let promises: Promise<NgModuleRef<any>>[] = [];
let storyData = new ReplaySubject(1);
let storyData = new ReplaySubject<StoryFnAngularReturnType>(1);

const moduleClass = class DynamicModule {};
const componentClass = class DynamicComponent {};

type DynamicComponentType = typeof componentClass;

function storyDataFactory<T>(data: Observable<T>) {
return (ngZone: NgZone) => new Observable((subscriber: Subscriber<T>) => {
const sub = data.subscribe(
(v: T) => { ngZone.run(() => subscriber.next(v)); },
(err) => { ngZone.run(() => subscriber.error(err)); },
() => { ngZone.run(() => subscriber.complete()); }
);

return () => {
sub.unsubscribe();
};
});
};

const getModule = (
declarations: (Type<any> | any[])[],
entryComponents: (Type<any> | any[])[],
Expand All @@ -34,13 +48,16 @@ const getModule = (
) => {
// Complete last ReplaySubject and create a new one for the current module
storyData.complete();
storyData = new ReplaySubject(1);
storyData = new ReplaySubject<StoryFnAngularReturnType>(1);
storyData.next(data);

const moduleMeta = {
declarations: [...declarations, ...(moduleMetadata.declarations || [])],
imports: [BrowserModule, FormsModule, ...(moduleMetadata.imports || [])],
providers: [{ provide: STORY, useValue: storyData }, ...(moduleMetadata.providers || [])],
providers: [
{ provide: STORY, useFactory: storyDataFactory(storyData.asObservable()), deps: [ NgZone ] },
...(moduleMetadata.providers || [])
],
entryComponents: [...entryComponents, ...(moduleMetadata.entryComponents || [])],
schemas: [...(moduleMetadata.schemas || [])],
bootstrap: [...bootstrap],
Expand Down

0 comments on commit 0e7f50f

Please sign in to comment.