fix(aio): revert resize to HostListener; delete device svc (#16143)
Angular change detection bug -> no page update on resize. Reverting to `@HostListener('window:resize', ['$event.target.innerWidth'])` cures it. Delete DeviceService which no longer serves a purpose. Adjusted affected AppComponent and LiveExample tests. PR Close #16143
This commit is contained in:
parent
1e848d696b
commit
f99cb96533
|
@ -9,7 +9,6 @@ import { of } from 'rxjs/observable/of';
|
|||
|
||||
import { AppComponent } from './app.component';
|
||||
import { AppModule } from './app.module';
|
||||
import { DeviceService } from 'app/shared/device.service';
|
||||
import { GaService } from 'app/shared/ga.service';
|
||||
import { SearchResultsComponent } from 'app/search/search-results/search-results.component';
|
||||
import { SearchBoxComponent } from 'app/search/search-box/search-box.component';
|
||||
|
@ -39,7 +38,6 @@ describe('AppComponent', () => {
|
|||
imports: [ AppModule ],
|
||||
providers: [
|
||||
{ provide: APP_BASE_HREF, useValue: '/' },
|
||||
{ provide: DeviceService, useClass: TestDeviceService },
|
||||
{ provide: GaService, useClass: TestGaService },
|
||||
{ provide: Http, useClass: TestHttp },
|
||||
{ provide: LocationService, useFactory: () => new MockLocationService(initialUrl) },
|
||||
|
@ -56,6 +54,7 @@ describe('AppComponent', () => {
|
|||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
|
||||
component.onResize(1033); // wide by default
|
||||
docViewer = fixture.debugElement.query(By.css('aio-doc-viewer')).nativeElement;
|
||||
hamburger = fixture.debugElement.query(By.css('.hamburger')).nativeElement;
|
||||
locationService = fixture.debugElement.injector.get(LocationService) as any;
|
||||
|
@ -349,13 +348,6 @@ describe('AppComponent', () => {
|
|||
|
||||
//// test helpers ////
|
||||
|
||||
class TestDeviceService {
|
||||
// Show sidenav next to the main doc when display width on current device is greater than this.
|
||||
readonly sideBySideWidth = 1032;
|
||||
// Default to "wide", desktop browser.
|
||||
displayWidth = new BehaviorSubject(this.sideBySideWidth + 1);
|
||||
}
|
||||
|
||||
class TestGaService {
|
||||
locationChanged = jasmine.createSpy('locationChanged');
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import { Title } from '@angular/platform-browser';
|
|||
|
||||
import { AutoScrollService } from 'app/shared/auto-scroll.service';
|
||||
import { CurrentNode, NavigationService, NavigationViews, NavigationNode, VersionInfo } from 'app/navigation/navigation.service';
|
||||
import { DeviceService } from 'app/shared/device.service';
|
||||
import { DocumentService, DocumentContents } from 'app/documents/document.service';
|
||||
import { DocViewerComponent } from 'app/layout/doc-viewer/doc-viewer.component';
|
||||
import { LocationService } from 'app/shared/location.service';
|
||||
|
@ -30,6 +29,7 @@ export class AppComponent implements OnInit {
|
|||
private isSideNavDoc = false;
|
||||
private previousNavView: string;
|
||||
|
||||
private sideBySideWidth = 1032;
|
||||
sideNavNodes: NavigationNode[];
|
||||
topMenuNodes: NavigationNode[];
|
||||
versionInfo: VersionInfo;
|
||||
|
@ -57,7 +57,6 @@ export class AppComponent implements OnInit {
|
|||
|
||||
constructor(
|
||||
private autoScrollService: AutoScrollService,
|
||||
private deviceService: DeviceService,
|
||||
private documentService: DocumentService,
|
||||
private locationService: LocationService,
|
||||
private navigationService: NavigationService,
|
||||
|
@ -66,6 +65,8 @@ export class AppComponent implements OnInit {
|
|||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.onResize(window.innerWidth);
|
||||
|
||||
/* No need to unsubscribe because this root component never dies */
|
||||
|
||||
this.documentService.currentDocument.subscribe(doc => {
|
||||
|
@ -101,8 +102,6 @@ export class AppComponent implements OnInit {
|
|||
this.navigationService.versionInfo.subscribe( vi => this.versionInfo = vi );
|
||||
|
||||
this.swUpdateNotifications.enable();
|
||||
|
||||
this.deviceService.displayWidth.subscribe(width => this.onResize(width));
|
||||
}
|
||||
|
||||
// Scroll to the anchor in the hash fragment.
|
||||
|
@ -116,8 +115,9 @@ export class AppComponent implements OnInit {
|
|||
this.autoScroll();
|
||||
}
|
||||
|
||||
@HostListener('window:resize', ['$event.target.innerWidth'])
|
||||
onResize(width) {
|
||||
this.isSideBySide = width > this.deviceService.sideBySideWidth;
|
||||
this.isSideBySide = width > this.sideBySideWidth;
|
||||
}
|
||||
|
||||
@HostListener('click', ['$event.target', '$event.button', '$event.ctrlKey', '$event.metaKey', '$event.altKey'])
|
||||
|
|
|
@ -15,7 +15,6 @@ import { SwUpdatesModule } from 'app/sw-updates/sw-updates.module';
|
|||
|
||||
import { AppComponent } from 'app/app.component';
|
||||
import { ApiService } from 'app/embedded/api/api.service';
|
||||
import { DeviceService } from 'app/shared/device.service';
|
||||
import { DocViewerComponent } from 'app/layout/doc-viewer/doc-viewer.component';
|
||||
import { DtComponent } from 'app/layout/doc-viewer/dt.component';
|
||||
import { EmbeddedModule } from 'app/embedded/embedded.module';
|
||||
|
@ -60,7 +59,6 @@ import { AutoScrollService } from 'app/shared/auto-scroll.service';
|
|||
],
|
||||
providers: [
|
||||
ApiService,
|
||||
DeviceService,
|
||||
GaService,
|
||||
Logger,
|
||||
Location,
|
||||
|
|
|
@ -3,9 +3,6 @@ import { By } from '@angular/platform-browser';
|
|||
import { Component, DebugElement, ElementRef } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
|
||||
import { DeviceService } from 'app/shared/device.service';
|
||||
import { LiveExampleComponent, EmbeddedPlunkerComponent } from './live-example.component';
|
||||
|
||||
const defaultTestPath = '/test';
|
||||
|
@ -19,14 +16,6 @@ describe('LiveExampleComponent', () => {
|
|||
let liveExampleContent: string;
|
||||
|
||||
//////// test helpers ////////
|
||||
class TestDeviceService {
|
||||
displayWidth = new BehaviorSubject(1001);
|
||||
}
|
||||
|
||||
class TestMobileDeviceService {
|
||||
// 1000 is the trigger width for "narrow mobile device""
|
||||
displayWidth = new BehaviorSubject(999);
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'aio-host-comp',
|
||||
|
@ -62,6 +51,8 @@ describe('LiveExampleComponent', () => {
|
|||
liveExampleDe.nativeElement.liveExampleContent = liveExampleContent;
|
||||
|
||||
fixture.detectChanges();
|
||||
liveExampleComponent.onResize(1033); // wide by default
|
||||
fixture.detectChanges();
|
||||
})
|
||||
.then(testFn);
|
||||
}
|
||||
|
@ -71,7 +62,6 @@ describe('LiveExampleComponent', () => {
|
|||
TestBed.configureTestingModule({
|
||||
declarations: [ HostComponent, LiveExampleComponent, EmbeddedPlunkerComponent ],
|
||||
providers: [
|
||||
{ provide: DeviceService, useClass: TestDeviceService },
|
||||
{ provide: Location, useClass: TestLocation }
|
||||
]
|
||||
})
|
||||
|
@ -295,15 +285,11 @@ describe('LiveExampleComponent', () => {
|
|||
|
||||
describe('when narrow display (mobile)', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
providers: [{ provide: DeviceService, useClass: TestMobileDeviceService }]
|
||||
});
|
||||
});
|
||||
|
||||
it('should be embedded style when no style defined', async(() => {
|
||||
setHostTemplate('<live-example></live-example>');
|
||||
testComponent(() => {
|
||||
liveExampleComponent.onResize(600); // narrow
|
||||
fixture.detectChanges();
|
||||
const hrefs = getHrefs();
|
||||
expect(hrefs[0]).toContain(defaultTestPath + '/eplnkr.html');
|
||||
});
|
||||
|
@ -312,6 +298,8 @@ describe('LiveExampleComponent', () => {
|
|||
it('should be embedded style even when flat-style requested', async(() => {
|
||||
setHostTemplate('<live-example flat-style></live-example>');
|
||||
testComponent(() => {
|
||||
liveExampleComponent.onResize(600); // narrow
|
||||
fixture.detectChanges();
|
||||
const hrefs = getHrefs();
|
||||
expect(hrefs[0]).toContain(defaultTestPath + '/eplnkr.html');
|
||||
});
|
||||
|
|
|
@ -1,12 +1,7 @@
|
|||
/* tslint:disable component-selector */
|
||||
import { Component, ElementRef, Input, OnInit, OnDestroy, AfterViewInit, ViewChild } from '@angular/core';
|
||||
import { Component, ElementRef, HostListener, Input, OnInit, AfterViewInit, ViewChild } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
|
||||
import { Subject } from 'rxjs/Subject';
|
||||
import 'rxjs/add/operator/takeUntil';
|
||||
|
||||
import { DeviceService } from 'app/shared/device.service';
|
||||
|
||||
const defaultPlnkrImg = 'plunker/placeholder.png';
|
||||
const imageBase = 'assets/images/';
|
||||
const liveExampleBase = 'content/live-examples/';
|
||||
|
@ -68,7 +63,7 @@ const zipBase = 'content/zips/';
|
|||
selector: 'live-example',
|
||||
templateUrl: 'live-example.component.html'
|
||||
})
|
||||
export class LiveExampleComponent implements OnInit, OnDestroy {
|
||||
export class LiveExampleComponent implements OnInit {
|
||||
|
||||
// Will force to embedded-style when viewport width is narrow
|
||||
// "narrow" value was picked based on phone dimensions from http://screensiz.es/phone
|
||||
|
@ -79,7 +74,6 @@ export class LiveExampleComponent implements OnInit, OnDestroy {
|
|||
exampleDir: string;
|
||||
isEmbedded = false;
|
||||
mode = 'disabled';
|
||||
onDestroy = new Subject();
|
||||
plnkr: string;
|
||||
plnkrName: string;
|
||||
plnkrImg: string;
|
||||
|
@ -88,7 +82,6 @@ export class LiveExampleComponent implements OnInit, OnDestroy {
|
|||
zip: string;
|
||||
|
||||
constructor(
|
||||
private deviceService: DeviceService,
|
||||
private elementRef: ElementRef,
|
||||
location: Location ) {
|
||||
|
||||
|
@ -154,12 +147,12 @@ export class LiveExampleComponent implements OnInit, OnDestroy {
|
|||
// Angular will sanitize this title when displayed so should be plain text.
|
||||
const title = this.elementRef.nativeElement.liveExampleContent;
|
||||
this.title = (title || this.attrs.title || 'live example').trim();
|
||||
|
||||
this.deviceService.displayWidth.takeUntil(this.onDestroy).subscribe(width => this.calcPlnkrLink(width));
|
||||
this.onResize(window.innerWidth);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy.next();
|
||||
@HostListener('window:resize', ['$event.target.innerWidth'])
|
||||
onResize(width) {
|
||||
this.calcPlnkrLink(width);
|
||||
}
|
||||
|
||||
toggleEmbedded () { this.showEmbedded = !this.showEmbedded; }
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
// Inquire about the state of the user's device
|
||||
import { Injectable } from '@angular/core';
|
||||
import { ReplaySubject } from 'rxjs/ReplaySubject';
|
||||
|
||||
@Injectable()
|
||||
export class DeviceService {
|
||||
|
||||
// Show sidenav next to the main doc when display width on current device is greater than this.
|
||||
readonly sideBySideWidth = 1032;
|
||||
|
||||
displayWidth = new ReplaySubject<number>(1);
|
||||
|
||||
constructor() {
|
||||
|
||||
if (window) {
|
||||
window.onresize = () => this.onResize();
|
||||
this.onResize();
|
||||
} else {
|
||||
// when no window, pretend the display is wide.
|
||||
this.onResize(this.sideBySideWidth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
onResize(width?: number) {
|
||||
this.displayWidth.next(width == null ? window.innerWidth : width);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue