我有一个基于行(类似表格)的自定义元素,它根据可绑定(bind)的列属性动态呈现其模板。它以字符串形式组成行模板,并使用 ViewCompiler、ViewFactory 和 View 进行渲染。
import {inject} from 'aurelia-dependency-injection';
import {bindable, ViewCompiler, ViewResources} from 'aurelia-templating';
@inject(ViewCompiler, ViewResources)
export class MyDynamicGrid {
@bindable columns: any[];
@bindable rows: any[];
constructor(viewCompiler: ViewCompiler, viewResources: ViewResources) {
const template = '<template><custom-element></custom-element></template>'; //this is rather complex in practice
viewResources.registerElement('custom-element', /* HtmlBehaviorResource? */);
this._viewFactory = viewCompiler.compile(template, viewResources);
}
_render() : void {
const view = this._viewFactory.create(/* some container */);
view.bind(someContext, someOverrideContext);
//attach view to the DOM
}
}
这工作正常,直到自定义模板包含标准 HTML 元素。一旦我开始将自定义元素放入模板中,它就会停止工作。它仍然呈现 HTML,但 Aurelia 不会附加自定义元素的行为。
我知道,所有自定义元素都应该“注册”才能使用。 “正常注册”发生在通过 <require>
的 View 中,或在 View 模型 @viewResources
中,或在全局注册。
但是,在这种特殊情况下,注入(inject)的 ViewCompiler
仅继承 View 模型父级的 View 资源。我的问题是:如何注册任何其他 View 资源?我知道 ViewCompiler
中的第二个参数。的compile
方法,但无法使其发挥作用。如果我在全局范围内注册它,我能够使其发挥作用的唯一方法。
注意:这个问题的重点是注册 View 资源。动态渲染效果很好
最佳答案
我通过深入研究 docs+github 找到了解决方案。我为两种不同的方法创建了两个示例:
- 手动创建
HtmlBehaviorResource
实例,用于注册一个特定元素。
示例(基于:https://github.com/aurelia/templating-resources/blob/master/test/repeat-integration.spec.js)
import {CustomElement} from 'my-components/my-custom-element';
import {inject, Container} from 'aurelia-dependency-injection';
import {ViewCompiler, ViewResources} from 'aurelia-templating';
import {metadata} from 'aurelia-metadata';
@inject(ViewCompiler, ViewResources, Container)
export class MyDynamicGrid {
//bindables and constructor is ommitted
init(): void {
const resource: HtmlBehaviorResource = metadata.get(metadata.resource, CustomElement);
resource.initialize(this._container, CustomElement);
resource.load(this._container, CustomElement)
.then(() => {
resource.register(this._viewResources);
this._viewFactory = viewCompiler.compile(template, this._viewResources);
});
}
}
备注:resource.register(this._viewResources);
行等效于 this._viewResources.registerElement('custom-element', resource);
。唯一的区别是首先从约定或装饰器中读取名称。
- 使用
ViewEngine
并导入整个模块。如果导入多个资源,甚至是不同类型(属性、元素、转换器等)并且来自不同文件,则这种方法更合适。
示例:
import {CustomElement} from 'my-components/my-custom-element';
import {inject} from 'aurelia-dependency-injection';
import {ViewCompiler, ViewResources, ViewEngine} from 'aurelia-templating';
@inject(ViewCompiler, ViewResources, ViewEngine)
export class MyDynamicGrid {
//bindables and constructor is ommitted
init(): void {
this._viewEngine
.importViewResources(['my-components/my-custom-element'], [undefined], this._viewResources)
.then(() => {
this._viewFactory = viewCompiler.compile(template, this._viewResources);
});
}
}
关于javascript - Aurelia - 如何为 ViewCompiler 注册 View 资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41468304/