Ionic-framework: Ionic V2: Sem provedor para NavController! Solução?

Criado em 10 dez. 2016  ·  15Comentários  ·  Fonte: ionic-team/ionic-framework

Versão iônica: (marque um com "x")
[] 1.x
[x] 2.x

Estou enviando um ... (marque um com "x")
[x] relatório de bug
[] solicitação de recurso
[] solicitação de suporte => Não envie solicitações de suporte aqui, use um destes canais: https://forum.ionicframework.com/ ou http://ionicworldwide.herokuapp.com/

Comportamento atual:
A injeção de NavController no construtor de serviço falha sem erro de provedor

Comportamento esperado:
trabalhar

Passos para reproduzir:
Esta classe gera erro (outra injeção de dep. Não gera nenhum erro)

import {Interceptor, InterceptedRequest, InterceptedResponse} from 'ng2-interceptors';
import {NavController, Platform, AlertController} from "ionic-angular";
import {Injectable, Injector} from "@angular/core";

@Injectable()
export class ServerInterceptorService implements Interceptor {

  constructor(public platform: Platform,
              public alertCtl: AlertController,
              public navCtl: NavController) {
  }

  public interceptBefore(request: InterceptedRequest): InterceptedRequest {
    // Do whatever with request: get info or edit it

    return request;
    /*
     You can return:
     - Request: The modified request
     - Nothing: For convenience: It's just like returning the request
     - <any>(Observable.throw("cancelled")): Cancels the request, interrupting it from the pipeline, and calling back 'interceptAfter' in backwards order of those interceptors that got called up to this point.
     */
  }

  public interceptAfter(response: InterceptedResponse): InterceptedResponse {
    // Do whatever with response: get info or edit it
    console.log("////////////", response)
    return response;
    /*
     You can return:
     - Response: The modified response
     - Nothing: For convenience: It's just like returning the response
     */
  }
}

e a classe acima substitui o provedor http em app.module.ts

providers:[
    ServerInterceptorService,
    {
      provide: Http,
      useFactory: interceptorFactory,
      deps: [XHRBackend, RequestOptions, ServerInterceptorService]
    },
...]

Outras dependências são injetadas corretamente.

Comentários muito úteis

@ m3l7 tente a seguir:

  constructor(
    protected app: App,
...
  get navCtrl(): NavController {
    return this.app.getRootNav();
  }

Todos 15 comentários

De acordo com https://forum.ionicframework.com/t/why-cant-i-import-navcontroller-and-viewcontroller-into-service-or-app/40999/26
está sendo dito

Apenas para comentar isso, você não deve injetar ViewController ou NavController em Service.
Este não é o propósito pretendido.

Então, por favor, diga-me, como devemos adicionar interceptores globais ao aplicativo, que agiriam dependendo de saber qual visualização ativa o usuário vê?

Devemos complicar nossas vidas dizendo a cada componente de visualização para ouvir ou assinar o serviço do interceptor se ele emitir algo dependendo de sua lógica interna, de forma que a visualização saiba se deve voltar para a página de login?

de acordo com
https://medium.com/coding-snippets/ionic-2-ui-alert-from-a-angular-2-service-221a2e526760#.spxbdpfz1

constructor(private app: IonicApp) {}
let alert = Alert.create({title: 'Error', message: message, buttons: ['OK']});
var nav = this.app.getActiveNav();
nav.present(alert

não funciona no rc3 para mim.

Posso estar perdendo algum ponto, mas ...

Só porque a equipe Angular ou outros dizem que _este é um componente de visualização e aquele é um objeto de serviço_, isolá-los totalmente apenas por causa de algum tipo de fixação de categorização não ajuda. Todos eles são objetos que podem e devem ser capazes de obter uma referência uns aos outros quando necessário.

Além disso, o NavController em um nível de aplicativo abstrato é mais um controlador global orquestrador do que uma simples classe de visualização acoplada. Portanto, como o NavController é "tão central", eu sugeriria repensar esse design ou adicionar um serviço centralizado de aplicativo ao módulo do núcleo do Ionic.

Há uma solução suja muito simples, dentro do seu app.component.ts o maravilhoso
@ViewChild ('carguardNav') navCtrl: NavController
pode ser passado para outros provedores de serviços, como

myGlobalService.nav = this.navCtrl

durante a fase de inicialização da plataforma e, em seguida, pode ser recuperado de seu outro serviço que depende e injetou MyGlobalService.

Olá! Desculpe que você está tendo problemas aqui. Portanto, o NavController não pode ser injetado em um serviço porque o serviço não tem um NavController. Isso significa que a injeção de dependência Angular não sabe qual NavController também deve obter uma referência, causando um erro. Uma coisa importante a lembrar é que isso não é central para nosso NavController, é um erro Angular DI padrão. Se estou entendendo seu caso de uso corretamente, você pode usar emissores de eventos para obter a mesma funcionalidade. Porque isso não é um erro de nossa parte, mas simplesmente como a injeção de dependência funciona no Angular 2. Vou encerrar esse problema por agora, mas recomendo fortemente que você abra uma solicitação de recurso para a ideia de serviço centralizado de navcontroller em todo o aplicativo que você menção acima. Obrigado por usar o Ionic!

Na verdade, eu fiz outra solução para quem possa interessar, estou usando eventos em todo o aplicativo para conectar componentes de visualização e serviço por meio do padrão IoC, significando os bons e velhos eventos de transmissão de serviços e assinando-os em componentes de visualização.

@barocsi Você se importa em postar sua solução? Estou tendo o mesmo problema.

Obrigou aquela merda a funcionar com getter e injetor

  constructor(
    protected injector: Injector
  ) {

...

  get navCtrl(): NavController {
    return this.injector.get(NavController);
  }

@bobrosoft você tem um exemplo de trabalho? Recebo "sem injetor para Navcontroller" novamente com o seu código

@ m3l7 tente a seguir:

  constructor(
    protected app: App,
...
  get navCtrl(): NavController {
    return this.app.getRootNav();
  }

@bobrosoft ok, funciona .. o problema é que ao chamar diretamente nav.push (MyComponent) obtenho um loop de dependências, então sou forçado a usar eventos capturados por um serviço de "roteador" que irá acionar o nav.push (esperando que essa solução funcione).

seria ótimo ter soluções de roteamento mais avançadas no ionic2 .. Estou apenas tentando fazer um interceptor 401 básico e redirecionar o aplicativo para a página de login

Ei @bobrosoft : Este é o caminho para isso!

construtor (plataforma @Inject (Platform), @Inject (NavController) navController) {
}

Isso é explicado aqui: https://github.com/driftyco/ionic/issues/5543

@mpeguero que não funcionará se o serviço (nós sobre serviços, certo?) instanciado em estágios anteriores e isso é tecnicamente próximo da minha primeira resposta. Eu verifiquei isso antes.

Essa solução

  constructor(
    protected app: App,
...
  get navCtrl(): NavController {
    return this.app.getRootNav();
  }

é melhor, mas também não é o ideal.

Nos documentos Ionic há solução. Funciona bem.

Obtenha o Outlook para Android http://aka.ms/ghei36

Na segunda-feira, 20 de março de 2017 às 4:44 AM -0400, "Vladimir Tolstikov" < [email protected] [email protected] > escreveu:

@mpeguero https://github.com/mpeguero que não funcionará se o serviço (nós sobre serviços, certo?) instanciado em estágios anteriores e isso é tecnicamente próximo da minha primeira resposta. Eu verifiquei isso antes.

Essa solução

construtor(
aplicativo protegido: aplicativo,
...
get navCtrl (): NavController {
retornar this.app.getRootNav ();
}

é melhor, mas também não é o ideal.

-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub https://github.com/driftyco/ionic/issues/9581#issuecomment-287701528 ou ignore o tópico https://github.com/notifications/unsubscribe-auth/ABvDpy- 6mn19VUnkSbBakAj11hsdEv1zks5rnjxygaJpZM4LJvpd .

então qual é a solução atual sobre este assunto? Tento abrir a página Logout se o Interceptor obtém um status HttpErrorResponse de 401 ou 403, mas não consigo fazer isso funcionar. Parece impossível, realmente.

Também é senso comum que um serviço global não injetaria e instanciaria NavController . Suponha que você esteja na página A, cujo componente está usando private navCtrl: NavController , e também está usando global-function-provider .
Agora, se este provedor também estiver injetando e usando seus próprios NavController , chamar o provedor do componente que o está usando irá bagunçar as coisas.

Na minha opinião, sempre que você quiser usar o navCtrl daquela Página, simplesmente passe-o como um parâmetro para a função global que você está usando.

Obrigado pelo problema! Este problema está sendo bloqueado para evitar comentários que não são relevantes ao problema original. Se isso ainda for um problema com a versão mais recente do Ionic, crie um novo problema e certifique-se de que o modelo esteja totalmente preenchido.

Esta página foi útil?
0 / 5 - 0 avaliações