Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I detect if an app is mobile and switch to a different app with angular2

I am building an application with a complex user interface. So complex, in fact, that I do not think that I can use ionic to simply create a mobile friendly version of the same app. Media queries, for example, can alter my css, but I will need a completely new structure and thus a new app.

Ideally, I'd like to have have a standard Angular2 app for desktop and and Ionic app for mobile. I'd prefer to have them in the same project folder so that I can share some code between them. I'm not even sure if this is possible.

Is there a way that I can I detect if the device is mobile and render a different application/application root?

like image 888
Nate May Avatar asked Jan 18 '17 01:01

Nate May


People also ask

How does AngularJS detect mobile devices?

ngDeviceDetector is a library which help detect the OS, browser and device in AngularJS application with ease.

Is mobile in angular?

Mobile Angular UI is an open-source framework for developing hybrid mobile apps. Mobile Angular UI makes use of Twitter Bootstrap and AngularJS that helps to create attractive HTML5 hybrid mobile and desktop apps.


1 Answers

You may want to try the DynamicComponentLoader. Disclaimer, I haven't used this since Angular2 Alpha. However, my approach was to detect the screen resolution and dynamically load a component into the main template. For small devices I loaded a tab layout and for larger a responsive grid. You could look into something like ng2-responsive for a more robust detection of resolutions and device types.

In Angular2 Alpha (sorry example is dated)

Plunker Example

template:

<div>
  <div #location></div>
</div>

component method:

setLayout(pSize:string) {
this.removeAll();

if(pSize === 'xs') {
  console.log('loading layout ' + pSize);

  this._dcl.loadNextToLocation(TabbedLayout, this._e).then((ref) => {
  ref.instance._ref = ref;
  this._children = ref;
});
} else {
  console.log('loading grid ' + pSize);

  this._dcl.loadNextToLocation(GridLayout, this._e).then((ref) => {
  ref.instance._ref = ref;
  this._children = ref;

});
}

}

Resolution Service: (Recommend something like ng2-responsive instead of my test service)

    import {Injectable} from '@angular/core';
    import {BehaviorSubject} from 'rxjs/BehaviorSubject';
    import {Observable} from 'rxjs/Observable';
    import 'rxjs/add/observable/fromEvent';
    import 'rxjs/add/operator/map';
    import 'rxjs/add/operator/pluck';
    import 'rxjs/add/operator/distinctUntilChanged';

    @Injectable()
    export class ResizeSvc {
       width$: Observable<number>;
       height$: Observable<number>;
       layout$: Observable<string>;
       constructor () {
    let windowSize$ = new BehaviorSubject(this.getWindowSize()); // most recent and subsequent values
    this.width$ = windowSize$.pluck('width').distinctUntilChanged(); 
    this.height$ = windowSize$.pluck('height').distinctUntilChanged();
    this.layout$ = windowSize$.pluck('layout').distinctUntilChanged(); // only observed distinct changes, e.g sm -> md -> lg, not lg -> lg -> lg 
    Observable.fromEvent(window, 'resize')
      .map(this.getWindowSize)
      .subscribe(windowSize$);
  }

  getWindowSize() {
    var size = 'na';
    if(window.innerWidth < 768) {
      size = 'xs';
    } else if (window.innerWidth < 992) {
      size = 'sm';
    } else if(window.innerWidth < 1200) {
      size = 'md'
    } else {
      size = 'lg';
    }
  return {
    height: window.innerHeight,
    width: window.innerWidth,
    layout: size
  };
}
}
like image 99
John McCann Avatar answered Oct 02 '22 16:10

John McCann