Bagaimana cara menyimpan konteks pengguna saat ini di AngularJS?

92

Saya memiliki AuthService, yang memasukkan pengguna, ia mengembalikan kembali objek json pengguna. Yang ingin saya lakukan adalah menyetel objek itu dan membuat semua perubahan tercermin di seluruh aplikasi (status masuk / keluar) tanpa harus menyegarkan laman.

Bagaimana saya mencapai ini dengan AngularJS?

Seni
sumber

Jawaban:

180

Cara termudah untuk melakukannya adalah dengan menggunakan layanan. Sebagai contoh:

app.factory( 'AuthService', function() {
  var currentUser;

  return {
    login: function() { ... },
    logout: function() { ... },
    isLoggedIn: function() { ... },
    currentUser: function() { return currentUser; }
    ...
  };
});

Anda kemudian dapat merujuk ini di salah satu pengontrol Anda. Kode berikut mengawasi perubahan nilai dari layanan (dengan memanggil fungsi yang ditentukan) dan kemudian menyinkronkan nilai yang diubah ke cakupan.

app.controller( 'MainCtrl', function( $scope, AuthService ) {
  $scope.$watch( AuthService.isLoggedIn, function ( isLoggedIn ) {
    $scope.isLoggedIn = isLoggedIn;
    $scope.currentUser = AuthService.currentUser();
  });
});

Dan kemudian, tentu saja, Anda dapat menggunakan informasi itu sesuka Anda; misalnya dalam petunjuk, templat, dll. Anda dapat mengulang ini (disesuaikan dengan apa yang perlu Anda lakukan) di pengontrol menu Anda, dll. Semuanya akan diperbarui secara otomatis saat Anda mengubah status pada layanan.

Apa pun yang lebih spesifik bergantung pada penerapan Anda.

Semoga ini membantu!

Josh David Miller
sumber
28
@ChrisNicola Sebenarnya, di AngularJS semua layanan adalah lajang. Jadi layanan dibuat pertama kali diminta (yaitu oleh pengontrol atau layanan lain) dan semua permintaan berikutnya untuk itu mengembalikan instance yang sama persis.
Josh David Miller
2
Bisa jadi, tetapi sebagai suatu fungsi kita dapat menghapus internal bagaimana kita menyimpan informasi itu dari API publik dan ke dalam API pribadi. Ini membuat pemfaktoran ulang nanti jauh lebih mudah. Tapi fungsinya masih akan mengembalikan boolean.
Josh David Miller
7
Ini mungkin pertanyaan bodoh ... tapi apa yang terjadi jika pengguna menyegarkan halaman - apakah informasi login hilang?
Tomba
10
@Tomba Itu pertanyaan yang bagus. :-) Memang info hilang saat refresh. Biasanya, Anda ingin menyimpan beberapa informasi sesi dalam cookie. Info sesi itu juga dapat diperiksa saat menyiapkan AuthService. Ini membantu tidak hanya untuk penyegaran halaman tetapi untuk seseorang yang membuka link di tab baru.
Josh David Miller
2
@PixMach Anda 100% benar tentang kurva pembelajaran. Pertanyaan Anda akan sangat bergantung pada kasus tertentu, tetapi berikut adalah beberapa pola umum. Pertahankan pemisahan masalah: UI yang terkait dengan memulai proses masuk terpisah dari autentikasi itu sendiri, yang terpisah dari status autentikasi, yang terpisah dari menu apa pun yang mungkin bergantung pada status tersebut. Nav / menu sering kali paling baik ditangani oleh satu pengontrol, dan status bersarang (a la ui-router) dan penyelesaian rute adalah cara yang baik untuk menjaga kontrol autentikasi KERING. Apa yang Anda tulis kedengarannya benar.
Josh David Miller
5

Saya akan mengubah tanggapan yang baik dari Josh dengan menambahkan bahwa, karena AuthService biasanya diminati oleh siapa pun (katakanlah, siapa pun kecuali tampilan masuk harus hilang jika tidak ada yang masuk), mungkin alternatif yang lebih sederhana adalah memberi tahu pihak yang berkepentingan menggunakan $rootScope.$broadcast('loginStatusChanged', isLoggedIn);(1 ) (2), sementara pihak yang berkepentingan (seperti pengontrol) akan mendengarkan menggunakan $scope.$on('loginStatusChanged', function (event, isLoggedIn) { $scope.isLoggedIn = isLoggedIn; }.

(1) $rootScopedimasukkan sebagai argumen layanan

(2) Perhatikan bahwa, dalam kasus operasi login asynchronous, Anda ingin memberi tahu Angular bahwa siaran akan mengubah banyak hal, dengan memasukkannya ke dalam $rootScope.$apply()fungsi.

Sekarang, berbicara tentang menjaga konteks pengguna di setiap / banyak pengontrol, Anda mungkin tidak akan senang mendengarkan perubahan login di setiap pengontrol, dan mungkin lebih suka mendengarkan hanya di pengontrol login paling atas, lalu menambahkan pengontrol sadar-login lainnya sebagai anak / pengendali tertanam yang satu ini. Dengan cara ini, pengontrol anak akan dapat melihat properti induk $ scope yang diwarisi seperti konteks pengguna Anda.

Javarome
sumber
4
Suara negatif untuk penjelasan yang salah tentang fungsi pabrik. Kesalahpahaman ini telah diatasi dalam komentar ini beberapa bulan sebelum Anda memposting jawaban Anda.
Rhys van der Waerden