在aurelia中组成html文件 [英] composing html file in aurelia
问题描述
我想在aurelia中实现类似于android中"include"的功能:
I'd like to achieve something similar as "include" in android but in aurelia:
如何在父视图中评估绑定并且不使用自定义元素的情况下,将纯HTML文件内容注入到我的视图中? 绑定innerhtml是不够的,因为根据文档,绑定表达式被绕过了.
How to inject a plain html file content into my view, with binding evaluated within the parent View, and without using a custom element? Binding innerhtml is not enough as, according to the doc, the bindings expressions are bypassed.
推荐答案
正如Ashley所言,使用<compose view="./your-view.html"></compose>
元素将与现有的HTML文件一起使用,并将继承父上下文.
As already said by Ashley, using <compose view="./your-view.html"></compose>
element will work with an existing HTML file and it will inherit the parent context.
如果要动态组成HTML(从文件,数据库或以编程方式构建),则使用ViewCompiler
将为您提供最佳的性能和灵活性,因为与compose
相比,这层要比compose
小一层aurelia如何在内部构建自定义元素.
If you want to compose HTML dynamically (from a file, database, or built-up programmatically) then using the ViewCompiler
will give you the best performance and flexibility, as this is one layer less than compose
compared to how aurelia builds custom elements internally.
我在这里对另一个不同但相关的问题给出了类似的答案:
I gave a similar answer to a different (but related) question here:
您将使用text
插件将HTML文件作为文本加载到变量中,然后将其传递给ViewCompiler.我为此有一个自定义元素,就性能而言,它可能并不比compose
好,但是在使用原始html作为输入时,它确实允许更多控制,并且您可以根据需要针对自己的情况进行自己的性能优化:
You'd use the text
plugin to load your HTML file as text into a variable, and then pass that to the ViewCompiler. I have a custom element for this which, in terms of performance, is probably not better than compose
but it does allow for more control when working with raw html as input and you could do your own performance optimizations specific to your situation as needed:
import * as markup from "text!./your-element.html";
export class SomeViewModel {
constructor() {
this.markup = markup;
}
}
视图:
<template>
<dynamic-html html.bind="markup"></dynamic-html>
</template>
出于完整性考虑,这是我将ViewCompiler封装在的自定义元素:
For completeness sake, here is the custom element I encapsulated the ViewCompiler in:
import {
customElement,
TaskQueue,
bindable,
ViewCompiler,
ViewSlot,
View,
ViewResources,
Container,
ViewFactory,
inlineView,
inject,
DOM
} from "aurelia-framework";
@customElement("dynamic-html")
@inlineView("<template><div></div></template>")
@inject(DOM.Element, TaskQueue, Container, ViewCompiler)
export class DynamicHtml {
@bindable()
public html: string;
public element: HTMLElement;
private tq: TaskQueue;
private container: Container;
private viewCompiler: ViewCompiler;
private runtimeView: View;
private runtimeViewSlot: ViewSlot;
private runtimeViewFactory: ViewFactory;
private runtimeViewAnchor: HTMLDivElement;
constructor(element, tq, container, viewCompiler) {
this.element = <HTMLElement>element;
this.tq = tq;
this.container = container;
this.viewCompiler = viewCompiler;
}
public bindingContext: any;
public overrideContext: any;
public bind(bindingContext: any, overrideContext: any): void {
this.bindingContext = bindingContext;
this.overrideContext = overrideContext;
if (this.html) {
this.htmlChanged(this.html, undefined);
}
}
public unbind(): void {
this.disposeView();
this.bindingContext = null;
this.overrideContext = null;
}
public needsApply: boolean = false;
public isAttached: boolean = false;
public attached(): void {
this.runtimeViewAnchor = <HTMLDivElement>this.element.firstElementChild;
this.isAttached = true;
if (this.needsApply) {
this.needsApply = false;
this.apply();
}
}
public detached(): void {
this.isAttached = false;
this.runtimeViewAnchor = null;
}
private htmlChanged(newValue: string, oldValue: void): void {
if (newValue) {
if (this.isAttached) {
this.tq.queueMicroTask(() => {
this.apply();
});
} else {
this.needsApply = true;
}
} else {
if (this.isApplied) {
this.disposeView();
}
}
}
private isApplied: boolean = false;
private apply(): void {
if (this.isApplied) {
this.disposeView();
}
this.compileView();
}
private disposeView(): void {
if (this.runtimeViewSlot) {
this.runtimeViewSlot.unbind();
this.runtimeViewSlot.detached();
this.runtimeViewSlot.removeAll();
this.runtimeViewSlot = null;
}
if (this.runtimeViewFactory) {
this.runtimeViewFactory = null;
}
if (this.runtimeView) {
this.runtimeView = null;
}
this.isApplied = false;
}
private compileView(): void {
this.runtimeViewFactory = createViewFactory(this.viewCompiler, this.container, this.html);
this.runtimeView = createView(this.runtimeViewFactory, this.container);
this.runtimeViewSlot = createViewSlot(this.runtimeViewAnchor);
this.runtimeViewSlot.add(this.runtimeView);
this.runtimeViewSlot.bind(this.bindingContext, this.overrideContext);
this.runtimeViewSlot.attached();
this.isApplied = true;
}
}
function createViewFactory(viewCompiler: ViewCompiler, container: Container, html: string): ViewFactory {
if (!html.startsWith("<template>")) {
html = `<template>${html}</template>`;
}
let viewResources: ViewResources = container.get(ViewResources);
let viewFactory = viewCompiler.compile(html, viewResources);
return viewFactory;
}
function createView(viewFactory: ViewFactory, container: Container): View {
let childContainer = container.createChild();
let view = viewFactory.create(childContainer);
return view;
}
function createViewSlot(containerElement: Element): ViewSlot {
let viewSlot = new ViewSlot(containerElement, true);
return viewSlot;
}
这篇关于在aurelia中组成html文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!