ng-be / 2016-app-ng-be-org

NG-BE 2016 pwa
Apache License 2.0
9 stars 3 forks source link

Encapsulate pages inside feature modules #53

Open SamVerschueren opened 7 years ago

SamVerschueren commented 7 years ago

Alright, this might be a little bit hard to explain, I'll do my best :).

So yesterday, I dived more into Ionic 2. I like how easy it is to get something good looking on the screen. What I dislike however is the structure. Pages are just components, nothing more nothing less. Why? Why aren't they modules that encapsulates everything from within that page. It could even encapsulate child pages... In my opinion, that would make much more sense.

Let's give you an example.

The schedule page has quite some html in the template file. Normally, you would work with dumb components to split everything apart. For instance, the session list is written like this.

    <ion-item-sliding *ngFor="let session of group.sessions" #slidingItem [attr.tag]="session.tags[0]"
                      [hidden]="session.hidden">

      <ion-item (click)="goToSessionDetail(session)">
        <h3>{{session.title}}</h3>
        <p>
          {{session.startDate.format('HH:mm')}} &mdash;
          {{session.endDate.format('HH:mm')}}:
          {{session.room.name}}
        </p>

        <ul class="tags">
          <li *ngFor="let tag of session.tags" [attr.tag]="tag" class="tag">
            {{tag}}
          </li>
        </ul>

        <ion-icon name="bookmark" item-right color="primary" *ngIf="!session.favorite && segment ==='all'"></ion-icon>
        <ion-icon name="bookmark" item-right color="secondary"
                  *ngIf="session.favorite && segment ==='all'"></ion-icon>

      </ion-item>

      <ion-item-options>
        <button ion-button color="favorite" (click)="toggleFavorite(slidingItem, session)" *ngIf="segment === 'all'">
          <span *ngIf="!session.favorite">Favorite session</span>
          <span *ngIf="session.favorite">Defavorite session</span>
        </button>
      </ion-item-options>

    </ion-item-sliding>

It would be much cleaner if we extracted the session item to a separate dumb component and work with a session input or something like that.

    <ion-item-sliding *ngFor="let session of group.sessions" #slidingItem [attr.tag]="session.tags[0]"
                      [hidden]="session.hidden">

      <session-item [session]="session"></session-item>

      <ion-item-options>
        <button ion-button color="favorite" (click)="toggleFavorite(slidingItem, session)" *ngIf="segment === 'all'">
          <span *ngIf="!session.favorite">Favorite session</span>
          <span *ngIf="session.favorite">Defavorite session</span>
        </button>
      </ion-item-options>

    </ion-item-sliding>

And embed the ion-item component inside the session-item.

With the current structure however, this would require us to actually bootstrap the SessionItemComponent at the root module of our application. Dirty!

Solution

  1. Create a ScheduleModule which encapsulates everything inside the schedule page. You could add services, other components, pipes, etc without having to bootstrap them at the root for everyone.
import { SchedulePage } from './schedule';

@NgModule({
  declarations: [
    SchedulePage
  ],
  entryComponents: [
    SchedulePage
  ]
})
export class ScheduleModule { }
  1. Create a index barrel file that exports the module and the page. We need the page so we can navigate to it.
export { ScheduleModule } from './schedule.module';
export { SchedulePage } from './schedule.page';
  1. Import in the AppModule and remove SchedulePage from entryComponents.

That's basically it. In my opinion, a much better separation which allows you to easily create extra dumb components in order to keep your code clean. The ConnectionService can now be part of the ScheduleModule (if we don't need it somewhere else) and follows the Angular 2 way of thinking.

Let me know what you think.

jvandemo commented 7 years ago

@SamVerschueren Sounds great to me. Largely aligns with how I do things in Angular 2 Web Applications using feature modules 👍

@samvloeberghs: Would be great to hear your thoughts as well. What do you think?

SamVerschueren commented 7 years ago

That's how I do it as well. Currently we have to bootstrap and expose services, components, pipes, ... in the root and they're visible and can be used by everyone which is usually not what you want.

I can do a small refactoring of one page and do a PR to make it more clear.

jvandemo commented 7 years ago

If Ionic 2 allows the use of feature modules, then I can't think of a reason not to use them.

Unless @samvloeberghs has any particular arguments against them here.

Thanks for your great work @SamVerschueren, much appreciated! 👍

SamVerschueren commented 7 years ago

They allow it, it's just not documented by them. It should be part of their tutorial imo.

Thanks for your great work @SamVerschueren, much appreciated! 👍

My pleasure :)

samvloeberghs commented 7 years ago

I'm all up for modules :) Modules all the way!!!

samvloeberghs commented 7 years ago

wontfix, repo deprecated