Here is the approach I have taken.
Organizational structure
mobile-view.component.html
<p> This content is for mobile view </p>
desktop-view.component.html
<p> This content is for desktop view </p>
mobile.component.ts
import { BaseComponent } from './base.component';
@Component({
selector: 'app-mobile-view',
templateUrl: './mobile-view.component.html'
})
export class MobileComponent extends BaseComponent { }
desktop.component.ts
import { BaseComponent } from './base.component';
@Component({
selector: 'app-desktop-view',
templateUrl: './desktop-view.component.html'
})
export class DesktopComponent extends BaseComponent { }
base.component.ts
@Component({
selector: 'app-root',
template: `<app-mobile-view *ngIf="isMobileView"></app-mobile-view>
<app-desktop-view *ngIf="!isMobileView"></app-desktop-view>`
})
export class BaseComponent implements {
isMobileView: boolean;
constructor(){
if (navigator.userAgent &&
(navigator.userAgent.match(/Android/i) ||
navigator.userAgent.match(/webOS/i) ||
navigator.userAgent.match(/iPhone/i) ||
navigator.userAgent.match(/BlackBerry/i) ||
navigator.userAgent.match(/Windows Phone/i))) {
this.isMobileView = true;
} else {
this.isMobileView = false;
}
}
ngOnInit() {
// code
}
// various methods
}
In this method, all main logic and binding variables are kept in base.component.ts file
Mobile component and Desktop component extend Base component to access all methods and variables
Note:- This code example is just a demonstration of what I have attempted.
Requirement :
- An AOT build is required.
If there is a better approach or standard practice for achieving this?
If there is a way to set the template dynamically based on the device that made the request. Refer to the code in base.component.html constructor for code to fetch userAgent information (provides info about the device making the request), which I am currently using.
Previous method used:-
main.component.html
@Component({
selector: 'app-root',
template: function () {
if (isMobileUser()) {
return require('./mobile-view.component.html');
} else {
return require('./desktop-view.component.html');
}
}(),
styleUrls: ['./main.component.scss']
})
export class MainComponent {
}
- This approach resulted in an AOT build failure
- and the use of function call in the component decorator is deprecated