Skip to content

Commit 99fc668

Browse files
jelbournkara
authored andcommitted
Revert "fix(portal): detect changes for portal hostview while before attaching. (#4370)" (#5131)
1 parent 7b5b18d commit 99fc668

File tree

6 files changed

+65
-34
lines changed

6 files changed

+65
-34
lines changed

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,21 @@ export class DomPortalHost extends BasePortalHost {
3737
*/
3838
attachComponentPortal<T>(portal: ComponentPortal<T>): ComponentRef<T> {
3939
let componentFactory = this._componentFactoryResolver.resolveComponentFactory(portal.component);
40-
let componentRef = componentFactory.create(portal.injector || this._defaultInjector);
41-
componentRef.hostView.detectChanges();
40+
let componentRef: ComponentRef<T>;
4241

4342
// If the portal specifies a ViewContainerRef, we will use that as the attachment point
4443
// for the component (in terms of Angular's component tree, not rendering).
4544
// When the ViewContainerRef is missing, we use the factory to create the component directly
4645
// and then manually attach the view to the application.
4746
if (portal.viewContainerRef) {
48-
portal.viewContainerRef.insert(componentRef.hostView);
47+
componentRef = portal.viewContainerRef.createComponent(
48+
componentFactory,
49+
portal.viewContainerRef.length,
50+
portal.injector || portal.viewContainerRef.parentInjector);
51+
4952
this.setDisposeFn(() => componentRef.destroy());
5053
} else {
54+
componentRef = componentFactory.create(portal.injector || this._defaultInjector);
5155
this._appRef.attachView(componentRef.hostView);
5256
this.setDisposeFn(() => {
5357
this._appRef.detachView(componentRef.hostView);

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

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -368,12 +368,6 @@ 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-
});
377371
});
378372
});
379373

@@ -410,15 +404,6 @@ class ArbitraryViewContainerRefComponent {
410404
constructor(public viewContainerRef: ViewContainerRef, public injector: Injector) { }
411405
}
412406

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-
422407

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

469454
// Create a real (non-test) NgModule as a workaround for
470455
// https://github.com/angular/angular/issues/10760
471-
const TEST_COMPONENTS = [
472-
PortalTestApp,
473-
ArbitraryViewContainerRefComponent,
474-
PizzaMsg,
475-
ComponentWithBoundVariable
476-
];
456+
const TEST_COMPONENTS = [PortalTestApp, ArbitraryViewContainerRefComponent, PizzaMsg];
477457
@NgModule({
478458
imports: [CommonModule, PortalModule],
479459
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.spec.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,15 @@ describe('MdDatepicker', () => {
3434
let adapter = new NativeDateAdapter();
3535
adapter.setLocale('en-US');
3636
return adapter;
37-
}}
37+
}},
3838
],
3939
declarations: [
4040
DatepickerWithFilterAndValidation,
4141
DatepickerWithFormControl,
4242
DatepickerWithMinAndMaxValidation,
4343
DatepickerWithNgModel,
4444
DatepickerWithStartAt,
45+
DatepickerWithStartView,
4546
DatepickerWithToggle,
4647
InputContainerDatepicker,
4748
MultiInputDatepicker,
@@ -203,6 +204,35 @@ describe('MdDatepicker', () => {
203204
});
204205
});
205206

207+
describe('datepicker with startView', () => {
208+
let fixture: ComponentFixture<DatepickerWithStartView>;
209+
let testComponent: DatepickerWithStartView;
210+
211+
beforeEach(async(() => {
212+
fixture = TestBed.createComponent(DatepickerWithStartView);
213+
fixture.detectChanges();
214+
215+
testComponent = fixture.componentInstance;
216+
}));
217+
218+
afterEach(async(() => {
219+
testComponent.datepicker.close();
220+
fixture.detectChanges();
221+
}));
222+
223+
it('should start at the specified view', () => {
224+
testComponent.datepicker.open();
225+
fixture.detectChanges();
226+
227+
const firstCalendarCell = document.querySelector('.mat-calendar-body-cell');
228+
229+
// When the calendar is in year view, the first cell should be for a month rather than
230+
// for a date.
231+
expect(firstCalendarCell.textContent)
232+
.toBe('JAN', 'Expected the calendar to be in year-view');
233+
});
234+
});
235+
206236
describe('datepicker with ngModel', () => {
207237
let fixture: ComponentFixture<DatepickerWithNgModel>;
208238
let testComponent: DatepickerWithNgModel;
@@ -698,6 +728,18 @@ class DatepickerWithStartAt {
698728
}
699729

700730

731+
@Component({
732+
template: `
733+
<input [mdDatepicker]="d" [value]="date">
734+
<md-datepicker #d startView="year"></md-datepicker>
735+
`,
736+
})
737+
class DatepickerWithStartView {
738+
date = new Date(2020, JAN, 1);
739+
@ViewChild('d') datepicker: MdDatepicker<Date>;
740+
}
741+
742+
701743
@Component({
702744
template: `<input [(ngModel)]="selected" [mdDatepicker]="d"><md-datepicker #d></md-datepicker>`,
703745
})

src/lib/datepicker/datepicker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ let datepickerUid = 0;
5757
styleUrls: ['datepicker-content.css'],
5858
host: {
5959
'class': 'mat-datepicker-content',
60-
'[class.mat-datepicker-content-touch]': 'datepicker?.touchUi',
60+
'[class.mat-datepicker-content-touch]': 'datepicker.touchUi',
6161
'(keydown)': '_handleKeydown($event)',
6262
},
6363
encapsulation: ViewEncapsulation.None,

src/lib/snack-bar/snack-bar.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,11 @@ export class MdSnackBar {
131131
let containerRef: ComponentRef<MdSnackBarContainer> = overlayRef.attach(containerPortal);
132132
containerRef.instance.snackBarConfig = config;
133133

134+
// The snackbar animation needs the content to be resolved in order to transform the bar
135+
// out of the view initially (so it can slide in). To make the content resolve, we manually
136+
// detect changes.
137+
containerRef.changeDetectorRef.detectChanges();
138+
134139
return containerRef.instance;
135140
}
136141

0 commit comments

Comments
 (0)