Reputation: 21
My approach is as below.
Folder structure
mobile-view.component.html
<p> this is mobile view</p>
desktop-view.component.html
<p> this is 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 approach my main logic and all binding variables reside in base.component.ts
Mobile component and Desktop component extends Base component to access all methods and variables
Note:- This is demo code just for understanding what i have tried.
Requirement :
Need any better approach or standard practice for achieving this
Need a way to set template dynamically based on device from which it is request. Refer base.component.html constructor for code of getting userAgent(provide info of device from which request is comming) which i am using currently.
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 {
}
Upvotes: 2
Views: 410
Reputation: 9764
You can follow this approach which is simpler when compared to above one. using ngContainer with ngTemplateoutlet, you can inject the template into the container based on condition.
@Component({
selector: 'app-mobiledesktop-view',
templateUrl: './mobiledesktop-view.component.html'
})
export class MobileDesktopComponent { }
**Template:**
<ng-template #mobileView>
This is mobile view
</ng-template>
<ng-template #desktopView>
This is desktop view
</ng-template>
<ng-container *ngTemplateOutlet="isDesktop ? desktopView : mobileView">
</ng-container>
Using Dynamic Component:
@Component({
selector: 'app-desktop-view',
template: 'This is desktop view'
})
export class AppDesktopComponent { }
@Component({
selector: 'app-mobile-view',
template: 'This is mobile view'
})
export class AppMobileComponent { }
@Component({
selector: 'app-container-view',
template: ' <ng-container #messagecontainer></ng-container>'
})
export class AppContainerComponent {
private componentRef;
@ViewChild('messagecontainer', { read: ViewContainerRef }) entry: ViewContainerRef;
constructor(private resolver: ComponentFactoryResolver) { }
ngAfterViewInit(){
const component = (isDesktop) ? AppDesktopComponent : AppMobileComponent;
const factory = this.resolver.resolveComponentFactory(component);
this.componentRef = this.entry.createComponent(factory);
//this.componentRef.instance.data = appData;
}
ngOnDestroy() {
this.componentRef.destroy();
}
}
Upvotes: 1