我正在编写一个应用程序,其中一些部分为SPA,一些页面在服务器端生成用于SEO.我选择了Aurelia.io框架,并使用增强方法在我的页面上启用自定义元素.但我找不到在我的服务器端页面上使用aurelia特定模板指令和插值的最佳方法.让我们从一个例子开始吧.
我的所有页面都包含动态标题.此标头将是名为my-cool-header的自定义元素.此标头将加载验证用户并显示其名称,或者,如果当前未对用户进行身份验证,则将显示指向登录的链接.页面正文将在服务器端生成并缓存.所以,我们会有类似的东西:
<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>
然后,我的标题将由以下定义:
import {UserService} from './user'; import {inject} from 'aurelia-framework'; @inject(UserService) export class MyCoolHeader { constructor(userService) { this.userService = userService; } async attached() { this.user = await this.userService.get(); } }
使用以下模板:
<template> <content></content> </template>
而这个引导脚本:
export function configure(aurelia) { aurelia.use .standardConfiguration() .developmentLogging() .globalResources('my-cool-header'); aurelia.start().then(a => a.enhance(document.body)); }
在此配置中,自定义元素已正确加载和实例化.但是,我无法访问< content>内的节点的viewmodel.节点.因此,所有插值(${user.name})和属性(show.bind)都将被忽略.如果我在我的内容模板中包含一个custom元素,只有在bootstrap中声明为global时才会加载它:忽略`标记.
我找到了一个解决方法,通过将自定义viewmodel设置为增强方法,然后将其注入我的自定义元素类,在阅读doc之后能够更改viewmodel.就像是 :
import {MainData} from './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)); }
自定义元素:
import {UserService} from './user'; import {inject} from 'aurelia-framework'; import {MainData} from './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(); } }
最后,如果我像这样更改我的模板,它将起作用:
<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>
解决方法
感谢您的线索,我找到了解决方案!
自定义元素需要构建自己的模板:
import {processContent,noView} from 'aurelia-framework'; @processContent(function(viewCompiler,viewResources,element,instruction) { instruction.viewFactory = viewCompiler.compile(`<template>${element.innerHTML}</template>`,instruction); element.innerHTML = ''; return false; }) @noView export class MyCustomElement { attached() { this.world = 'World!'; this.display = true; } }
然后,在我从服务器的视图中,我们可以插入并需要自定义元素!
<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>
我写了一个装饰器来帮助创建这种增强的自定义元素:https://github.com/hadrienl/aurelia-enhanced-template
Plusdedétailsenrançaisurmon blog:https://blog.hadrien.eu/2016/02/04/amelioration-progressive-avec-aurelia-io/
编辑:< require>并没有真正使用这个解决方案.我得再挖一次:(