diff --git a/src/lib/core/portal/dom-portal-host.ts b/src/lib/core/portal/dom-portal-host.ts index 7a2ebf360779..c2244fd4d551 100644 --- a/src/lib/core/portal/dom-portal-host.ts +++ b/src/lib/core/portal/dom-portal-host.ts @@ -29,21 +29,17 @@ export class DomPortalHost extends BasePortalHost { */ attachComponentPortal(portal: ComponentPortal): ComponentRef { let componentFactory = this._componentFactoryResolver.resolveComponentFactory(portal.component); - let componentRef: ComponentRef; + let componentRef = componentFactory.create(portal.injector || this._defaultInjector); + componentRef.hostView.detectChanges(); // If the portal specifies a ViewContainerRef, we will use that as the attachment point // for the component (in terms of Angular's component tree, not rendering). // When the ViewContainerRef is missing, we use the factory to create the component directly // and then manually attach the view to the application. if (portal.viewContainerRef) { - componentRef = portal.viewContainerRef.createComponent( - componentFactory, - portal.viewContainerRef.length, - portal.injector || portal.viewContainerRef.parentInjector); - + portal.viewContainerRef.insert(componentRef.hostView); this.setDisposeFn(() => componentRef.destroy()); } else { - componentRef = componentFactory.create(portal.injector || this._defaultInjector); this._appRef.attachView(componentRef.hostView); this.setDisposeFn(() => { this._appRef.detachView(componentRef.hostView); diff --git a/src/lib/core/portal/portal.spec.ts b/src/lib/core/portal/portal.spec.ts index 6ba347c833b1..16dc8c8058e5 100644 --- a/src/lib/core/portal/portal.spec.ts +++ b/src/lib/core/portal/portal.spec.ts @@ -368,6 +368,12 @@ describe('Portals', () => { expect(spy).toHaveBeenCalled(); }); + + it('should run change detection in the created component when a ComponentPortal is attached', + () => { + host.attach(new ComponentPortal(ComponentWithBoundVariable, someViewContainerRef)); + expect(someDomElement.textContent).toContain('initial value'); + }); }); }); @@ -404,6 +410,15 @@ class ArbitraryViewContainerRefComponent { constructor(public viewContainerRef: ViewContainerRef, public injector: Injector) { } } +/** Simple component with a bound variable in the template */ +@Component({ + selector: 'bound-text', + template: '

{{text}}

' +}) +class ComponentWithBoundVariable { + text: string = 'initial value'; +} + /** Test-bed component that contains a portal host and a couple of template portals. */ @Component({ @@ -453,7 +468,12 @@ class PortalTestApp { // Create a real (non-test) NgModule as a workaround for // https://github.com/angular/angular/issues/10760 -const TEST_COMPONENTS = [PortalTestApp, ArbitraryViewContainerRefComponent, PizzaMsg]; +const TEST_COMPONENTS = [ + PortalTestApp, + ArbitraryViewContainerRefComponent, + PizzaMsg, + ComponentWithBoundVariable +]; @NgModule({ imports: [CommonModule, PortalModule], exports: TEST_COMPONENTS, diff --git a/src/lib/datepicker/datepicker-content.html b/src/lib/datepicker/datepicker-content.html index 0f3a70ec7dff..86829a041fec 100644 --- a/src/lib/datepicker/datepicker-content.html +++ b/src/lib/datepicker/datepicker-content.html @@ -1,10 +1,10 @@ + [id]="datepicker?.id" + [startAt]="datepicker?.startAt" + [startView]="datepicker?.startView" + [minDate]="datepicker?._minDate" + [maxDate]="datepicker?._maxDate" + [dateFilter]="datepicker?._dateFilter" + [selected]="datepicker?._selected" + (selectedChange)="datepicker?._selectAndClose($event)"> diff --git a/src/lib/datepicker/datepicker.ts b/src/lib/datepicker/datepicker.ts index 41302c21c0e3..5297b91adaab 100644 --- a/src/lib/datepicker/datepicker.ts +++ b/src/lib/datepicker/datepicker.ts @@ -50,7 +50,7 @@ let datepickerUid = 0; styleUrls: ['datepicker-content.css'], host: { 'class': 'mat-datepicker-content', - '[class.mat-datepicker-content-touch]': 'datepicker.touchUi', + '[class.mat-datepicker-content-touch]': 'datepicker?.touchUi', '(keydown)': '_handleKeydown($event)', }, encapsulation: ViewEncapsulation.None,