Side-menu badges (conference app reference)


#1

I’m using the Ionic 2 conference app as a template for displaying menu items. I’d like to show a badge item on menu items, based on values in a service.

I can certainly extend the PageInterface to include a static badgeCount, and adjust the markup to match. But how can I get that to bind to a property so it updates when the service value updates? For example, below, where I have badgeCount set to 3, can I bind that to a service property somehow?

Menu:

  <ion-list>
    <ion-list-header>
      Features
    </ion-list-header>
    <button ion-item menuClose *ngFor="let p of appPages" (click)="openPage(p)" name="{{p.buttonName}}">
      <ion-icon item-left [name]="p.icon" [color]="isActive(p)"></ion-icon>
      {{p.title}} <ion-badge *ngIf="p?.badgeCount > 0">{{p.badgeCount}}</ion-badge>
    </button>
  </ion-list>

New Page Definition:

{ title: 'Notifications' , component: NotificationsPage, icon: 'alarm', buttonName: 'btnNotifications', badgeCount: 3 }

#2

If you need two-way data binding (so that your template view can update your controller or provider data, and both ways), you should use [(ngModel)]. I refer you to the Angular docs:

https://angular.io/docs/ts/latest/api/forms/index/NgModel-directive.html


#3

Hi @FrancoisIonic - I’m aware of standard 2-way binding using ngModel. This is a bit different, in that there is a simple page object that has the contents of the menu. I’d like that simple object to somehow have a dynamic property to use for binding.

I did get one thing to work - in place of binding it to an object directly I used a method, which can evaluate the page and get notification info. Not completely what I was looking for, but it seems to work.

HTML:

    <button ion-item menuClose *ngFor="let p of appPages" (click)="openPage(p)" name="{{p.buttonName}}">
      <ion-icon item-left [name]="p.icon" [color]="isActive(p)"></ion-icon>
      {{p.title}} <ion-badge *ngIf="notificationCount(p) > 0">{{notificationCount(p)}}</ion-badge>
    </button>

TS:

notificationCount(page: PageInterface) {
    switch (page.title) {
        case 'Notifications': return this.notificationsService.driverNotificationCount; 
    }
}

#4

Observables would be how I would go at this. I would put a BehaviorSubject<number> badgeCount property in each page, and use the AsyncPipe to unwrap it like so: {{p.badgeCount | async}}.

Then you just call page.badgeCount.next() with new values and let Angular’s change detection handle the rest.