Skip to content

Commit 28d2ddd

Browse files
josephperrottandrewseguin
authored andcommitted
fix(portal): detect changes for portal hostview while before attaching. (angular#4370)
1 parent 1f93cdb commit 28d2ddd

File tree

4 files changed

+33
-17
lines changed

4 files changed

+33
-17
lines changed

src/lib/core/portal/dom-portal-host.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,17 @@ export class DomPortalHost extends BasePortalHost {
2929
*/
3030
attachComponentPortal<T>(portal: ComponentPortal<T>): ComponentRef<T> {
3131
let componentFactory = this._componentFactoryResolver.resolveComponentFactory(portal.component);
32-
let componentRef: ComponentRef<T>;
32+
let componentRef = componentFactory.create(portal.injector || this._defaultInjector);
33+
componentRef.hostView.detectChanges();
3334

3435
// If the portal specifies a ViewContainerRef, we will use that as the attachment point
3536
// for the component (in terms of Angular's component tree, not rendering).
3637
// When the ViewContainerRef is missing, we use the factory to create the component directly
3738
// and then manually attach the view to the application.
3839
if (portal.viewContainerRef) {
39-
componentRef = portal.viewContainerRef.createComponent(
40-
componentFactory,
41-
portal.viewContainerRef.length,
42-
portal.injector || portal.viewContainerRef.parentInjector);
43-
40+
portal.viewContainerRef.insert(componentRef.hostView);
4441
this.setDisposeFn(() => componentRef.destroy());
4542
} else {
46-
componentRef = componentFactory.create(portal.injector || this._defaultInjector);
4743
this._appRef.attachView(componentRef.hostView);
4844
this.setDisposeFn(() => {
4945
this._appRef.detachView(componentRef.hostView);

src/lib/core/portal/portal.spec.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,12 @@ describe('Portals', () => {
368368

369369
expect(spy).toHaveBeenCalled();
370370
});
371+
372+
it('should run change detection in the created component when a ComponentPortal is attached',
373+
() => {
374+
host.attach(new ComponentPortal(ComponentWithBoundVariable, someViewContainerRef));
375+
expect(someDomElement.textContent).toContain('initial value');
376+
});
371377
});
372378
});
373379

@@ -404,6 +410,15 @@ class ArbitraryViewContainerRefComponent {
404410
constructor(public viewContainerRef: ViewContainerRef, public injector: Injector) { }
405411
}
406412

413+
/** Simple component with a bound variable in the template */
414+
@Component({
415+
selector: 'bound-text',
416+
template: '<p>{{text}}</p>'
417+
})
418+
class ComponentWithBoundVariable {
419+
text: string = 'initial value';
420+
}
421+
407422

408423
/** Test-bed component that contains a portal host and a couple of template portals. */
409424
@Component({
@@ -453,7 +468,12 @@ class PortalTestApp {
453468

454469
// Create a real (non-test) NgModule as a workaround for
455470
// https://github.com/angular/angular/issues/10760
456-
const TEST_COMPONENTS = [PortalTestApp, ArbitraryViewContainerRefComponent, PizzaMsg];
471+
const TEST_COMPONENTS = [
472+
PortalTestApp,
473+
ArbitraryViewContainerRefComponent,
474+
PizzaMsg,
475+
ComponentWithBoundVariable
476+
];
457477
@NgModule({
458478
imports: [CommonModule, PortalModule],
459479
exports: TEST_COMPONENTS,
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<md-calendar cdkTrapFocus
2-
[id]="datepicker.id"
3-
[startAt]="datepicker.startAt"
4-
[startView]="datepicker.startView"
5-
[minDate]="datepicker._minDate"
6-
[maxDate]="datepicker._maxDate"
7-
[dateFilter]="datepicker._dateFilter"
8-
[selected]="datepicker._selected"
9-
(selectedChange)="datepicker._selectAndClose($event)">
2+
[id]="datepicker?.id"
3+
[startAt]="datepicker?.startAt"
4+
[startView]="datepicker?.startView"
5+
[minDate]="datepicker?._minDate"
6+
[maxDate]="datepicker?._maxDate"
7+
[dateFilter]="datepicker?._dateFilter"
8+
[selected]="datepicker?._selected"
9+
(selectedChange)="datepicker?._selectAndClose($event)">
1010
</md-calendar>

src/lib/datepicker/datepicker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ let datepickerUid = 0;
4949
styleUrls: ['datepicker-content.css'],
5050
host: {
5151
'class': 'mat-datepicker-content',
52-
'[class.mat-datepicker-content-touch]': 'datepicker.touchUi',
52+
'[class.mat-datepicker-content-touch]': 'datepicker?.touchUi',
5353
'(keydown)': '_handleKeydown($event)',
5454
},
5555
encapsulation: ViewEncapsulation.None,

0 commit comments

Comments
 (0)