Angular 4中如何从Login组件修改Navbar组件的布尔变量?
userRights.service for Cross-Component Access The cleanest, most maintainable way to handle this is to move your 15 permission boolean variables out of navbar.component.ts and into your existing userRights.service. Since Angular services are singletons, both your LoginComponent and NavbarComponent can interact with the same shared state—no messy component-to-component direct communication needed.
Here's a step-by-step implementation:
1. Update UserRightsService to Manage Permission State
First, refactor your service to hold and expose the permission state, using a BehaviorSubject to automatically notify components when permissions change:
import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs/BehaviorSubject'; @Injectable() export class UserRightsService { // Initialize all permissions to false by default private permissionState = new BehaviorSubject({ canAddHardware: false, canChangeUserRights: false, canEditBlog: false, // ... add all 15 permission flags here }); // Expose an observable for components to subscribe to public permissions$ = this.permissionState.asObservable(); // Method to update permissions (called from LoginComponent) updateUserPermissions(newPermissions: Partial<typeof this.permissionState.value>) { // Merge new permissions with existing state const updatedState = { ...this.permissionState.value, ...newPermissions }; this.permissionState.next(updatedState); } // Optional: Get current permission state synchronously if needed getCurrentPermissions() { return this.permissionState.value; } }
2. Update LoginComponent to Set Permissions on Login
After validating the user's credentials and fetching their rights (likely from an API), call the service's updateUserPermissions method to set the flags:
import { Component } from '@angular/core'; import { UserRightsService } from './path-to/user-rights.service'; @Component({ selector: 'app-login', templateUrl: './login.component.html' }) export class LoginComponent { constructor(private userRightsService: UserRightsService) {} onLogin() { // Replace with your actual login logic (API call, credential validation) const loggedInUserRights = this.fetchUserRightsFromApi(); // Update the service with the user's permissions this.userRightsService.updateUserPermissions({ canAddHardware: loggedInUserRights.canAddHardware, canChangeUserRights: loggedInUserRights.canChangeUserRights, canEditBlog: loggedInUserRights.canEditBlog, // ... map all 15 permissions from your API response }); } private fetchUserRightsFromApi() { // Mock API response—replace with your real endpoint call return { canAddHardware: true, canChangeUserRights: false, canEditBlog: true, // ... other permissions }; } }
3. Update NavbarComponent to React to Permission Changes
You have two clean options to sync the navbar with the service's state:
Option A: Use the Async Pipe in the Template (Recommended)
Avoid manual subscriptions by using Angular's async pipe to automatically listen for permission changes:
In navbar.component.ts:
import { Component } from '@angular/core'; import { UserRightsService } from './path-to/user-rights.service'; @Component({ selector: 'app-navbar', templateUrl: './navbar.component.html' }) export class NavbarComponent { // Expose the permissions observable to the template permissions$ = this.userRightsService.permissions$; constructor(private userRightsService: UserRightsService) {} }
In navbar.component.html:
<ul class="navbar-nav"> <li class="nav-item" *ngIf="(permissions$ | async).canAddHardware"> <a class="nav-link" routerLink="/add-hardware">Add Hardware</a> </li> <li class="nav-item" *ngIf="(permissions$ | async).canChangeUserRights"> <a class="nav-link" routerLink="/user-rights">Manage User Rights</a> </li> <!-- ... repeat for all 15 nav items --> </ul>
Option B: Subscribe to Changes in the Component
If you prefer to keep local boolean variables in the navbar (for more complex logic), subscribe to the service's observable:
import { Component, OnInit, OnDestroy } from '@angular/core'; import { UserRightsService } from './path-to/user-rights.service'; import { Subscription } from 'rxjs/Subscription'; @Component({ selector: 'app-navbar', templateUrl: './navbar.component.html' }) export class NavbarComponent implements OnInit, OnDestroy { canAddHardware: boolean = false; canChangeUserRights: boolean = false; canEditBlog: boolean = false; // ... all 15 boolean variables private permissionSubscription: Subscription; constructor(private userRightsService: UserRightsService) {} ngOnInit() { // Subscribe to permission changes this.permissionSubscription = this.userRightsService.permissions$.subscribe(permissions => { this.canAddHardware = permissions.canAddHardware; this.canChangeUserRights = permissions.canChangeUserRights; this.canEditBlog = permissions.canEditBlog; // ... update all variables here }); } // Clean up subscription to prevent memory leaks ngOnDestroy() { this.permissionSubscription.unsubscribe(); } }
4. Optional: Persist Permissions Across Page Reloads
To keep permissions when the user refreshes the page, add logic to save/load the state from localStorage:
Add these methods to UserRightsService:
private readonly STORAGE_KEY = 'user_permissions'; constructor() { // Load saved permissions on service initialization const savedPermissions = localStorage.getItem(this.STORAGE_KEY); if (savedPermissions) { this.permissionState.next(JSON.parse(savedPermissions)); } } updateUserPermissions(newPermissions: Partial<typeof this.permissionState.value>) { const updatedState = { ...this.permissionState.value, ...newPermissions }; this.permissionState.next(updatedState); // Save to localStorage localStorage.setItem(this.STORAGE_KEY, JSON.stringify(updatedState)); }
内容的提问来源于stack exchange,提问作者Sithys

