Dynamic content with Angular

81
Dynamic content with Angular a journey with @filipbech @IMPACTdigitaldk

Transcript of Dynamic content with Angular

Filip

@filipbech

🇩🇰

#weAreHiring #Denmark

https://www.facebook.com/groups/ngAarhus/

https://developers.google.com/experts/people/filip-bruun-bech-larsen

…enough about melet’s use Angular for dynamic content

Why

• We build for CMS-editors, so we need Angular to

behave in that context

• When Angular2 (old name) was announced it

seemed so awesome…

Let’s do like angular 1

need to bootstrap a component

…but we have no root app?

Bootstrapping multiple

applications

• its a little harder to maintain state between

applications (but possible)

• the cms now needs to know what components are

angular-components, so they can all be

bootstrapped.(and their DOM-nodes if multiple of the

same component)

Initial data

• We need to feed data (settings, initial data) into

some of the components (from the cms), and put

content inside them.

Because

• Root-components cannot have inputs

• Root-components cannot use content-projection

(transclusion)

https://github.com/angular/angular/issues/1858

How about a <body>-

component then?

Eeeewwwww

• even though it works - it feels terrible and wrong!

• and we need the parser at runtime

• so no AOT and bad perf

We need a SPA

Single Page Application

• so we can also share state between routes

• animate route-changes

• and much more…

Demo-timeto heighten the suspense…

It starts with a router

…thats not very dynamic

We have too many routes

with no patterns

• “/“ is a frontpage

• “/om/os” is a content-page

• “/mejeri“ is a category-page

• “/mejeri/ost“ is a sub-category-page

• “/ost-i-skiver-mild-13-cheasy-200-g” is a product-page

So I talked to the Angular

team…

…let the CMS

output route-config

Two issues with that

approach

• Need to build and invalidate the bundle’s cache

every time an editor makes a change

• Users get stuck on the route-config they get at first

load

One route to rule them all

**-route + generic

PageComponent

Get the data in a

resolve

PageResolve is just a class with resolve(route)-method on it

In angular 1.x we could use templateFactory and

select a template based on the api-response

But we cannot do that in Angular 2+, because

there is no template-parser at runtime

All possible

PageComponents with

individual *ngIf’s

Eeeewwwww

Even though all the *ngIfs in the template are AOT

compiled into something more acceptable…

It still seems wrong to have it in the template!

but (for now) it

works…

until you navigate

around(nothing happens)

you’re not changing the

route

just its options(so: no new resolve, no new ngOnInit)

Refactoring

• Listen for route-changes and handle resolving data

manually

The problem cascades

• When we go from one product-detail-page to

another product-detail-page…

• Refactor init-logic into ngOnChanges

Then came rc4

ComponentFactoryResolver adds beauty

and power to generic components…

The theory

[generic-page]

directive

What components

should be available?

or (if you are building a lib)

ANALYSE_FOR_ENTRY_COMPONE

NTS

Watch Sean Landsmans talk from ngVikings:

https://opbeat.com/community/posts/understanding-aot-and-dynamic-components-in-angular-by-sean-landsman/

Sweeeetall we ever wanted

Without all the uglywe control components-instantiation, so

they can use regular ngOnInit

AOT#justWorks

Add PageComponents to

ngModule entryComponents

Faster and lighterInitial parse goes from 450ms to 250ms

Without AOT

With AOT

Same approach for the

dynamic content spots

Server Side Rendering

SEO, social previews

and

faster perceived load-

timesAngular Universal is so hot right now… (going into core)

Hard to wrap your

head around universal

The idea

• server.module and a client.module

• they both import the app.module

• server and client module then replaces the

dependencies (through the universal-module) that

are different with appropriate environment-versions

(eg. xhr or node-fetch, DOM or virtual-dom)

Can’t touch this (the

DOM)(no window, querySelector, localstorage without wrappers)

browser.module.ts and node.module.ts

Maintaining statewe want to maintain state, so we don’t re-do all fetches

and calculations when the client boots up

enter UNIVERSAL_CACHE

We made it to nirvana

https://github.com/filipbech/ng2-dynamic-spa