komponen aplikasi pembaruan sudut 2 dari komponen outlet router

Saya menggunakan sudut 2 rc1 dan router baru @angular/router

Dalam komponen aplikasi saya memiliki bagian nav dan outlet router

<nav>   
    <a *ngIf="auth?.userName == null" [routerLink]="['/login']">Login</a>
    <a *ngIf="auth?.userName != null" (click)="logout()">Logout</a>
    {{auth?.userName}}
</nav> 
<router-outlet></router-outlet>

Saya menyuntikkan layanan login ke dalam komponen aplikasi dan berlangganan acara di ngOnInit

ngOnInit() {
    this.loginService.loginSuccess.subscribe(this.loginSuccess);

} 
ngOnDestroy() {
    this.loginService.loginSuccess.unsubscribe();
}
private loginSuccess(res: IAuthResponse) {
    this.auth = res;
}  

ketika saya menavigasi ke halaman/komponen rute '/ login' saya, layanan login saya disuntikkan dan layanan login mendefinisikan suatu peristiwa

@Output() loginSuccess = new EventEmitter<IAuthResponse>();

dan setelah berhasil login di layanan saya, layanan login memunculkan acara tersebut

this.loginSuccess.next(response);

Saya dapat menyetel breakpoint di komponen aplikasi pada loginSucess berlangganan dan data diteruskan, namun 'ini' tidak ditentukan.

private loginSuccess(res: IAuthResponse) {
    this.auth = res;  //this is undefind
} 

bagaimana cara memperbarui komponen aplikasi dari peristiwa yang dipicu dari layanan yang digunakan dalam komponen yang dihosting di outlet router


person Dan Soltesz    schedule 12.05.2016    source sumber


Jawaban (2)


Tidak yakin apa yang Anda maksud dengan "dan data telah dikirimkan".

@Output() loginSuccess = new EventEmitter<IAuthResponse>();

di komponen yang ditambahkan oleh router (LoginComponent) tidak melakukan apa pun. @Input() dan @Output() pada komponen yang dirutekan tidak didukung.

Cukup masukkan LoginService ke komponen yang dirutekan dan pancarkan peristiwa tersebut menggunakan observasi di komponen login.

@Injectable() 
export class LoginService {
  changes:BehaviorSubject = new BehaviorSubject(false);
}
export class LoginComponent {
  constructor(private loginService:LoginService) {}

  onLogin() {
    this.loginService.changes.next(true);
  }
}
export class NavComponent {
  constructor(private loginService:LoginService) {}

  onLogin() {
    this.loginService.changes.subscribe(status => this.isLoggedIn = status);
  }
}
person Günter Zöchbauer    schedule 12.05.2016
comment
Saya menyuntikkan loginService ke dalam loginComponent dan loginService telah mendefinisikan @output eventEmitter. Ketika acara dimunculkan dari layanan login, komponen aplikasi menerima acara dengan data (IAuthResponse) tetapi 'ini' di komponen aplikasi adalah null/tidak ditentukan - person Dan Soltesz; 12.05.2016
comment
Oke, EventEmitter sebaiknya hanya digunakan di komponen. @Output() dalam suatu layanan tidak ada artinya. Apakah Anda memiliki function() alih-alih ()=> di mana pun dalam kode Anda atau apakah Anda meneruskan suatu fungsi di mana saja? - person Günter Zöchbauer; 12.05.2016
comment
mengubah @output() EventEmitter dari layanan saya ke SubjectBehavior menghasilkan perilaku benar yang saya cari. terima kasih atas klarifikasi kapan/di mana menggunakan atribut output. - person Dan Soltesz; 12.05.2016
comment
Besar! Oke, pada akhirnya Behavior' part made the difference. EventEmitter` adalah Subject (tanpa Behavior dan tim Angular mungkin akan mengubah implementasinya ke sesuatu yang berbeda pada akhirnya). Perbedaannya adalah BehaviorSubject langsung memancarkan event terakhir ke pelanggan baru sedangkan dengan Subject pelanggan hanya mendapatkan event yang dipancarkan setelah mereka berlangganan. - person Günter Zöchbauer; 12.05.2016

Sepertinya ini bisa menjadi solusi untuk masalah saya: meneruskan peristiwa dari anak ke orang tua yang menggunakan outlet router, namun sepertinya RC1 telah mengubah cara kerja BehaviorSubject. Menggunakan metode di atas:

changes:BehaviorSubject = new BehaviorSubject(false);

memberikan kesalahan yang mengatakan BehaviorSubject memerlukan deklarasi tipe, jadi saya mencoba keduanya

changes:BehaviorSubject<boolean> = new BehaviorSubject(false);
    as well as
changes:BehaviorSubject<any> = new BehaviorSubject(false);

dan dapat dikompilasi dengan baik, namun saat menjalankan aplikasi, muncul kesalahan non-deskriptif berupa:

zone.js:323 SyntaxError: Unexpected token <
Evaluating http://localhost:3000/node_modules/rxjs/index.js
Error loading http://localhost:3000/app/main.js
at SystemJSLoader.__exec
(http://localhost:3000/node_modules/systemjs/dist/system.src.js:1395:16)
at entry.execute 

Saya berasumsi ada sesuatu yang berubah dengan rxjs dan BehaviorSubject

person Shar    schedule 24.05.2016
comment
Itu tidak berhubungan dengan BehaviorSubject itu sendiri. Pesan kesalahan pertama adalah beberapa pengaturan konfigurasi tentang pemeriksaan tipe statis (saya tidak tahu detailnya di sini karena saya sendiri menggunakan Dart). Pesan kesalahan kedua juga terkait dengan penyiapan proyek Anda. Tolong jangan menambahkan pertanyaan lanjutan sebagai jawaban. Lebih baik buat pertanyaan baru dengan tautan ke pertanyaan yang Anda sampaikan. - person Günter Zöchbauer; 24.05.2016
comment
Saya mengetahui apa itu, mereka memindahkan lokasi BehaviorSubject. Sebelumnya di bawah rxjs/subject/BehaviorSubject, sekarang di rxjs/BehaviorSubject, yang memperbaikinya. Selain itu, mereka (Stackoverflow) tidak mengizinkan saya menambahkan komentar ke postingan lain karena saya memerlukan peringkat 500 atau semacamnya, tetapi mereka mengizinkan postingan jawaban...lanjutkan gambar - person Shar; 24.05.2016