OnsenUI / OnsenUI

Mobile app development framework and SDK using HTML5 and JavaScript. Create beautiful and performant cross-platform mobile apps. Based on Web Components, and provides bindings for Angular 1, 2, React and Vue.js.
https://onsen.io/
8.83k stars 1.01k forks source link

Is there any router for angular 2+ in onsen ui? #2505

Closed digish777 closed 6 years ago

digish777 commented 6 years ago

Hi, I am an angular developer. I amusing Onsen UI for Hybrid develpment. I need to know, if there is a router for Onsen in case of Angular flavor of yours?

Thanks in advance.

puku0x commented 6 years ago

@digish777 Unfortunately, no. We should use only ons-navigator for now.

I tried using Angular router with Onsen UI but it was difficult because I could not use transition animations without <ons-navigator> and OnsNavigator injection token was not created until <ons-navigator> was rendered (you will see StaticInjectorError when you set routes and resolvers).

puku0x commented 6 years ago

I heard Ionic v4 could use with Angular router. https://github.com/ionic-team/ionic

It is still beta version, but it may worth trying it!

puku0x commented 6 years ago

Anyway, thank you @digish777. I found ngx-onsenui used ReflectiveInjector, which has been deprecated since Angular 5, during I was investigating this issue.

This means ngx-onsenui will not work because ReflectiveInjector will be omitted in Angular 7 which is planned to be released in this November. I will make an issue for it later!

digish777 commented 6 years ago

My point is, I want to add a guard or check before the routing happens, how am I supposed to do it?

digish777 commented 6 years ago

Is there any central place where I can track when routing happens?

puku0x commented 6 years ago

@digish777 ons-navigator is. You can handle the routing events such as prepush, postpush, prepop, postpop.

@Component({
  selector: 'ons-page[page1]',
  templateUrl: './page1.component.html',
  styleUrls: [ './page1.component.css' ]
})
export class Page1Component implements OnInit, OnDestroy {
  constructor(private navi: OnsNavigator) {}

  onPrepush = (event) => {
    console.log(event);
    if (someGuardConditions) {
      event.cancel();  // Cancel pushPage
    }
  }

  ngOnInit() {
    document.querySelector('ons-navigator').addEventListener('prepush', this.onPrepush);
  }

  ngOnDestroy() {
    document.querySelector('ons-navigator').removeEventListener('prepush', this.onPrepush);
  }

  goToPage2() {
    this.navi.nativeElement.pushPage(Page2Component);
  }

}

https://onsen.io/v2/api/angular2/ons-navigator.html

digish777 commented 6 years ago

any idea, how to show default error page?

puku0x commented 6 years ago

How about using HttpInterceptor and OnsNavigator.resetToPage() ?

I think it is better to use onsNotification.alert() or onsNotification.toast() for such case, though.

digish777 commented 6 years ago

on injecting. private navigator: OnsNavigator in http interceptor, I get error: NullInjectorError: No provider for OnsNavigator!

puku0x commented 6 years ago

Oops, I forgot OnsNavigator could not be injected until <ons-navigator> was rendered.

If you are using NgRx or some Flux libraries, you can dispatch an action,

import { Store} from '@ngrx/store';

@Injectable()
export class ErrorInterceptor implements HttpInterceptor {

  constructor(private store: Store<any>) { }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const req = request.clone();
    return next.handle(req).pipe(
      catchError(res => {
        switch (res.status) {
          case 500:
            this.store.dispatch(new ShowErrorPage());
            break;
        }
      })
    );
  }
}

and show the error page.

import { Actions, ofType } from '@ngrx/effects';

@Component({
  selector: 'ons-page[page1]',
  templateUrl: './page1.component.html',
  styleUrls: ['./page1.component.scss']
})
export class Page1Component implements OnInit, OnDestroy {
  private readonly onDestroy$ = new EventEmitter();

  constructor(
    private store: Store<any>,
    private actions$: Actions,
    private navi: OnsNavigator
  ) { }

  ngOnInit() {
    this.actions$.pipe(
      takeUntil(this.onDestroy$),
      ofType(PageActionTypes.ShowErrorPage),
    ).subscribe(() => {
      this.navi.resetToPage(ErrorPageComponent);
    });
  }

  ngOnDestroy() {
    this.onDestroy$.emit();
  }
}

It looks too much complex. I recommend to use onsNotification.alert().

digish777 commented 6 years ago

how to check device type?