Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "fix(portal): detect changes for portal hostview while before attaching. (#4370)" #5131

Merged
merged 3 commits into from
Jun 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions src/lib/core/portal/dom-portal-host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,21 @@ export class DomPortalHost extends BasePortalHost {
*/
attachComponentPortal<T>(portal: ComponentPortal<T>): ComponentRef<T> {
let componentFactory = this._componentFactoryResolver.resolveComponentFactory(portal.component);
let componentRef = componentFactory.create(portal.injector || this._defaultInjector);
componentRef.hostView.detectChanges();
let componentRef: ComponentRef<T>;

// 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) {
portal.viewContainerRef.insert(componentRef.hostView);
componentRef = portal.viewContainerRef.createComponent(
componentFactory,
portal.viewContainerRef.length,
portal.injector || portal.viewContainerRef.parentInjector);

this.setDisposeFn(() => componentRef.destroy());
} else {
componentRef = componentFactory.create(portal.injector || this._defaultInjector);
this._appRef.attachView(componentRef.hostView);
this.setDisposeFn(() => {
this._appRef.detachView(componentRef.hostView);
Expand Down
22 changes: 1 addition & 21 deletions src/lib/core/portal/portal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,12 +368,6 @@ 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');
});
});
});

Expand Down Expand Up @@ -410,15 +404,6 @@ class ArbitraryViewContainerRefComponent {
constructor(public viewContainerRef: ViewContainerRef, public injector: Injector) { }
}

/** Simple component with a bound variable in the template */
@Component({
selector: 'bound-text',
template: '<p>{{text}}</p>'
})
class ComponentWithBoundVariable {
text: string = 'initial value';
}


/** Test-bed component that contains a portal host and a couple of template portals. */
@Component({
Expand Down Expand Up @@ -468,12 +453,7 @@ 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,
ComponentWithBoundVariable
];
const TEST_COMPONENTS = [PortalTestApp, ArbitraryViewContainerRefComponent, PizzaMsg];
@NgModule({
imports: [CommonModule, PortalModule],
exports: TEST_COMPONENTS,
Expand Down
16 changes: 8 additions & 8 deletions src/lib/datepicker/datepicker-content.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<md-calendar cdkTrapFocus
[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)">
[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)">
</md-calendar>
44 changes: 43 additions & 1 deletion src/lib/datepicker/datepicker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,15 @@ describe('MdDatepicker', () => {
let adapter = new NativeDateAdapter();
adapter.setLocale('en-US');
return adapter;
}}
}},
],
declarations: [
DatepickerWithFilterAndValidation,
DatepickerWithFormControl,
DatepickerWithMinAndMaxValidation,
DatepickerWithNgModel,
DatepickerWithStartAt,
DatepickerWithStartView,
DatepickerWithToggle,
InputContainerDatepicker,
MultiInputDatepicker,
Expand Down Expand Up @@ -203,6 +204,35 @@ describe('MdDatepicker', () => {
});
});

describe('datepicker with startView', () => {
let fixture: ComponentFixture<DatepickerWithStartView>;
let testComponent: DatepickerWithStartView;

beforeEach(async(() => {
fixture = TestBed.createComponent(DatepickerWithStartView);
fixture.detectChanges();

testComponent = fixture.componentInstance;
}));

afterEach(async(() => {
testComponent.datepicker.close();
fixture.detectChanges();
}));

it('should start at the specified view', () => {
testComponent.datepicker.open();
fixture.detectChanges();

const firstCalendarCell = document.querySelector('.mat-calendar-body-cell');

// When the calendar is in year view, the first cell should be for a month rather than
// for a date.
expect(firstCalendarCell.textContent)
.toBe('JAN', 'Expected the calendar to be in year-view');
});
});

describe('datepicker with ngModel', () => {
let fixture: ComponentFixture<DatepickerWithNgModel>;
let testComponent: DatepickerWithNgModel;
Expand Down Expand Up @@ -698,6 +728,18 @@ class DatepickerWithStartAt {
}


@Component({
template: `
<input [mdDatepicker]="d" [value]="date">
<md-datepicker #d startView="year"></md-datepicker>
`,
})
class DatepickerWithStartView {
date = new Date(2020, JAN, 1);
@ViewChild('d') datepicker: MdDatepicker<Date>;
}


@Component({
template: `<input [(ngModel)]="selected" [mdDatepicker]="d"><md-datepicker #d></md-datepicker>`,
})
Expand Down
2 changes: 1 addition & 1 deletion src/lib/datepicker/datepicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,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,
Expand Down
5 changes: 5 additions & 0 deletions src/lib/snack-bar/snack-bar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ export class MdSnackBar {
let containerRef: ComponentRef<MdSnackBarContainer> = overlayRef.attach(containerPortal);
containerRef.instance.snackBarConfig = config;

// The snackbar animation needs the content to be resolved in order to transform the bar
// out of the view initially (so it can slide in). To make the content resolve, we manually
// detect changes.
containerRef.changeDetectorRef.detectChanges();

return containerRef.instance;
}

Expand Down