Goku
Goku

Reputation: 1663

How do I tell which component is currently active Angular 5

I'm trying to make a settings button that dynamically changes its contents based on which component the user is currently viewing. I'm not sure what the standard practice is for doing this. I'm thinking that the correct way would be to use some type of built in angular directive that tells me which router link is currently in use, then use that in the settings component template to change the DOM using an *ngIf. I could read the URL and do it that way, but it seems incorrect. I suppose I could put an "isAlive" flag in each component, but that seems like a lot of work for something so standard for most websites, so i'm guessing this is not the right solution either. Any suggestions with a code example?

Here is an example parent component template (app component)

<nav ="navbar navbar-toggleable-md navbar-inverse bg-primary fixednav">
            <li class="nav-item">
                <a class="nav-link" routerLink="/checklist" routerLinkActive="active">
                   Checklist
                </a>
            </li>
            <li class="nav-item">
                <a class="nav-link" routerLink="/otherComponent" routerLinkActive="active">
                   OtherComponent
                </a>
            </li>
</nav>

Here is the settings template I'm talking about.

    <div *ngIf="someRouterThing.checklistComponent.Active" class="settings">
      <div class="panel-body navbar navbar-inverse bg-primary">
          <!-- Rounded switches -->
        <div>
          <label class="switch">
              <input type="checkbox" [checked]="checklistSettings.hideCheckedEnabled" (change)="toggleHideChecked()">
              <span class="slider round"></span>
          </label> Hide Checked
        </div>
        <div>
            <label class="switch">
                <input type="checkbox" [checked]="checklistSettings.hideHiddenEnabled" (change)="toggleHideHidden()">
                <span class="slider round"></span>
            </label> Hide Hidden
        </div>
      </div>
    </div>

    <div *ngIf="someRouterThing.otherComponent.Active class="settings">
       todo- add settings stuff that is different from above
    </div>

Upvotes: 2

Views: 6403

Answers (3)

Martin Parenteau
Martin Parenteau

Reputation: 73761

The router outlet has an activate event, with the loaded component as the $event parameter. You can use it to know which component is currently loaded, as shown in this stackblitz.

In the template:

<router-outlet (activate)="onActivate($event)"></router-outlet>

In the component code:

export class AppComponent {

  routerOutletComponent: object;
  routerOutletComponentClassName: string;

  onActivate(event: any): void {
    this.routerOutletComponent = event;
    this.routerOutletComponentClassName= event.constructor.name;
  }
}

Upvotes: 1

tom van green
tom van green

Reputation: 1734

You can create a service which will keep track on what options to show.

The service could look something like this:

@Injectable()
export class OptionsVisibilityService {
    checklistOptionsVisible = new BehaviorSubject<boolean>(false);        
    otherOptionsVisible = new BehaviorSubject<boolean>(false);
}

In your components you can update the state in the OnInit and OnDestroy lifecycle events:

@Component({/** ... */})
export class ChecklistComponent implements OnInit, OnDestroy {
    constructor(private optionsVisibility: OptionsVisibilityService) {
    }

    ngOnInit() {
        this.optionsVisibility.checklistOptionsVisible.next(true);
    }
    ngOnDestroy() {
        this.optionsVisibility.checklistOptionsVisible.next(false);
    }
}

Make the visibility service available in the component where you display the options:

export class OptionsButtonComponent {

    checklist$: Observable<boolean>;
    other$: Observable<boolean>;
    constructor(optionsVisibility: OptionsVisibilityService) {
        this.checklist$ = optionsVisibility.checklistOptionsVisible.asObservable();
        this.other$ = optionsVisibility.otherOptionsVisible.asObservable();
    }
}

Then use it in the template:

<div *ngIf="checklist$ | async">
    <!-- Show checklist options -->

</div>
<div *ngIf="other$ | async">
    <!-- Show other options -->
</div>

Upvotes: 0

progman
progman

Reputation: 386

You can assign a Boolean variable and change it to true inside component's constructor.Then call that Boolean value in view part (app.component.html).

Whenever the user goes/views that page the value which assigns in constructor will pass to view page (app.component.html).You can assign that value in *ngIf.

Upvotes: 0

Related Questions