Làm cách nào để lưu trữ ngữ cảnh người dùng hiện tại trong AngularJS?


92

Tôi có AuthService, đăng nhập một người dùng, nó trả về một đối tượng json người dùng. Những gì tôi muốn làm là thiết lập đối tượng đó và có tất cả các thay đổi được phản ánh trên toàn ứng dụng (trạng thái đăng nhập / đăng xuất) mà không cần phải làm mới trang.

Tôi sẽ thực hiện điều này như thế nào với AngularJS?

Câu trả lời:


180

Cách dễ nhất để thực hiện điều này là sử dụng một dịch vụ. Ví dụ:

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

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

Sau đó, bạn có thể tham chiếu điều này trong bất kỳ bộ điều khiển nào của mình. Đoạn mã sau theo dõi những thay đổi trong giá trị từ dịch vụ (bằng cách gọi hàm được chỉ định) và sau đó đồng bộ hóa các giá trị đã thay đổi với phạm vi.

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

Và sau đó, tất nhiên, bạn có thể sử dụng thông tin đó theo cách nào bạn thấy phù hợp; ví dụ: trong chỉ thị, trong mẫu, v.v. Bạn có thể lặp lại điều này (tùy chỉnh theo những gì bạn cần làm) trong bộ điều khiển menu của mình, v.v. Tất cả sẽ được cập nhật tự động khi bạn thay đổi trạng thái trên dịch vụ.

Bất cứ điều gì cụ thể hơn tùy thuộc vào việc triển khai của bạn.

Hi vọng điêu nay co ich!


28
@ChrisNicola Trên thực tế, trong AngularJS tất cả các dịch vụ đều là đơn lẻ. Vì vậy, dịch vụ được tạo ngay lần đầu tiên nó được yêu cầu (tức là bởi một bộ điều khiển hoặc một dịch vụ khác) và tất cả các yêu cầu tiếp theo cho nó đều trả về cùng một phiên bản chính xác.
Josh David Miller

2
Có thể là như vậy, nhưng là một chức năng, chúng tôi có thể xóa nội dung bên trong của cách chúng tôi lưu trữ thông tin đó khỏi API công khai và vào API riêng tư. Điều này làm cho việc tái cấu trúc sau này dễ dàng hơn nhiều. Nhưng hàm sẽ vẫn trả về một boolean.
Josh David Miller

7
Đây có thể là một câu hỏi ngu ngốc ... nhưng điều gì sẽ xảy ra nếu người dùng làm mới trang - thông tin đăng nhập có bị mất không?
Tomba

10
@Tomba Đó là một câu hỏi hay. :-) Thật vậy, thông tin bị mất khi làm mới. Thông thường, bạn sẽ muốn lưu trữ một số thông tin phiên trong cookie. Thông tin phiên đó cũng có thể được kiểm tra khi thiết lập AuthService. Điều này không chỉ giúp làm mới trang mà còn giúp ích cho ai đó đang mở liên kết trong tab mới.
Josh David Miller

2
@PixMach Bạn nói đúng 100% về lộ trình học tập. Câu hỏi của bạn sẽ phụ thuộc rất nhiều vào từng trường hợp cụ thể, nhưng đây là một số mẫu chung. Giữ tách biệt các mối quan tâm: giao diện người dùng liên quan đến việc bắt đầu đăng nhập tách biệt với chính xác thực, tách biệt với trạng thái của xác thực, tách biệt với bất kỳ menu nào có thể phụ thuộc vào trạng thái đã nói. Điều hướng / menu thường được xử lý tốt nhất bởi một bộ điều khiển duy nhất và các trạng thái lồng nhau (a la ui-router) và giải quyết tuyến đường là một cách tốt để giữ cho các điều khiển xác thực KHÔ. Những gì bạn đã viết có vẻ đúng.
Josh David Miller

5

Tôi sẽ sửa đổi phản hồi tốt của Josh bằng cách thêm rằng, vì một AuthService thường được bất kỳ ai quan tâm (giả sử bất kỳ ai trừ chế độ xem đăng nhập sẽ biến mất nếu không có ai đăng nhập), có thể một giải pháp thay thế đơn giản hơn là thông báo cho các bên quan tâm đang sử dụng $rootScope.$broadcast('loginStatusChanged', isLoggedIn);(1 ) (2), trong khi các bên quan tâm (chẳng hạn như bộ điều khiển) sẽ lắng nghe bằng cách sử dụng $scope.$on('loginStatusChanged', function (event, isLoggedIn) { $scope.isLoggedIn = isLoggedIn; }.

(1) $rootScopeđược đưa vào làm đối số của dịch vụ

(2) Lưu ý rằng, trong trường hợp có khả năng xảy ra hoạt động đăng nhập không đồng bộ, bạn sẽ muốn thông báo cho Angular rằng chương trình phát sóng sẽ thay đổi mọi thứ, bằng cách đưa nó vào một $rootScope.$apply()hàm.

Bây giờ, nói về việc giữ bối cảnh người dùng trong mọi / nhiều bộ điều khiển, bạn có thể không hài lòng khi lắng nghe các thay đổi đăng nhập ở mọi người trong số họ và có thể chỉ thích nghe trong bộ điều khiển đăng nhập trên cùng, sau đó thêm các bộ điều khiển nhận biết đăng nhập khác khi còn nhỏ / bộ điều khiển nhúng của cái này. Bằng cách này, bộ điều khiển trẻ em sẽ có thể thấy các thuộc tính $ scope gốc được kế thừa, chẳng hạn như ngữ cảnh người dùng của bạn.


4
Bị phản đối vì giải thích sai chức năng của nhà máy. Sự hiểu lầm này đã được giải quyết trong bình luận này vài tháng trước khi bạn đăng câu trả lời của mình.
Rhys van der Waerden
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.