javascript - How to enhance a server side generated page with Aurelia.io? -
i'm writing app parts spa , pages generated on server side seo. i've chosen aurelia.io framework , use enhance
method enable custom elements on pages. can't find best way use aurelia specific template directives , interpolation on server side page. let's start exemple.
all of pages contains dynamic header. header custom element named my-cool-header
. header load authentified user , display name, or, if no user authentified, link signin displayed. body of page generated on server side , cached. so, we'll have :
<html> <body> <my-cool-header> <img src="logo.png"> <div show.bind="user">${user.name}</div> <div show.bind="!user"><a href="/signin">sign-in</a></div> </my-cool-header> <div>cachabled content</div> </body> </html>
then, header defined :
import {userservice} './user'; import {inject} 'aurelia-framework'; @inject(userservice) export class mycoolheader { constructor(userservice) { this.userservice = userservice; } async attached() { this.user = await this.userservice.get(); } }
with following template :
<template> <content></content> </template>
and bootstrap script :
export function configure(aurelia) { aurelia.use .standardconfiguration() .developmentlogging() .globalresources('my-cool-header'); aurelia.start().then(a => a.enhance(document.body)); }
in configuration, custom element loaded , instanciated. but, can't access viewmodel of node inside <content>
node. so, interpolation (${user.name}) , attributes (
show.bind) ignored. if include custom-element in content template, loaded if declared global in bootstrap : the
` tag ignored.
i've found workaround able change viewmodel after reading doc setting custom viewmodel enhance method , then, injecting custom element class. :
import {maindata} './main-data'; export function configure(aurelia) { const maindata = aurelia.container.get(maindata); aurelia.use .standardconfiguration() .developmentlogging() .globalresources('my-cool-header'); aurelia.start().then(a => a.enhance(maindata, document.body)); }
custom element:
import {userservice} './user'; import {inject} 'aurelia-framework'; import {maindata} './main-data'; @inject(userservice, maindata) export class mycustomelement { constructor(userservice, maindata) { this.userservice = userservice; this.maindata = maindata; } async attached() { this.maindata.user = await this.userservice.get(); } }
and finally, if change template that, work :
<html> <body> <my-cool-header user.bind="user"> <img src="logo.png"> <div show.bind="user">${user.name}</div> <div show.bind="!user"><a href="/signin">sign-in</a></div> </my-cool-header> <div>cachabled content</div> </body> </html>
i can't believe right way because it's ugly , not resolve problem of <require>
tag. question : best way ?
thanks clues, found solution!
custom element need construct own template:
import {processcontent, noview} 'aurelia-framework'; @processcontent(function(viewcompiler, viewresources, element, instruction) { instruction.viewfactory = viewcompiler.compile(`<template>${element.innerhtml}</template>`, viewresources, instruction); element.innerhtml = ''; return false; }) @noview export class mycustomelement { attached() { this.world = 'world!'; this.display = true; } }
then, in view server, can interpolate , require custom elements!
<body> <my-custom-element> <require="./other-custom-element"></require> <p if.bind="display">hello ${world}</p> <other-custom-element></other-custom-element> </my-custom-element> </body>
i've wrote decorator creating kind of enhanced custom elements : https://github.com/hadrienl/aurelia-enhanced-template
plus de détails en français sur mon blog : https://blog.hadrien.eu/2016/02/04/amelioration-progressive-avec-aurelia-io/
edit: <require>
not working solution. have dig again :(
Comments
Post a Comment