如何使用Aurelia动态增强HTML

问题描述 投票:1回答:1

我们将所有页面内容和博客帖子等存储在WordPress中,使用其API在我们的Aurelia应用程序中呈现数据。这很好用;

<div class="excerpt" innerhtml.bind="post.excerpt.rendered"></div>

作者现在希望能够链接到弹出窗口或在他们的博客文章中使用route-href或其他自定义Aurelia属性,但是使用innerhtml.bind添加到页面的代码不会被Aurelia解析。

我喜欢Aurelia中正常的<a href="...">“正常工作” - 但我们有很多自定义属性(如<button popup="name-of-popup">...</button>,作者无法使用)。

我们怎样才能克服这一点?

编辑:随着@bigopon的评论,我已经开始了一些事情,但仍然无法让它发挥作用。要么我在搜索时很糟糕,要么文档在TemplatingEngine.enhance()方法上有点缺乏,但我尝试创建这样的自定义属性:

import {Aurelia, inject, TemplatingEngine} from 'aurelia-framework';

@inject(Element, Aurelia, TemplatingEngine)
export class AureliaEnhanceCustomAttribute {
    constructor (el, aurelia, templatingEngine) {
        this.el = el;
        this.aurelia = aurelia; // NOTE: I've never done this before - is it even correct?
        this.templatingEngine = templatingEngine;
    }

    attached () {
        this.el.innerHTML = this.value;

        // NOTE: Without checking for this we get an endless loop of attached() calls
        if (!this.el.classList.contains('au-target')) {
            this.templatingEngine.enhance({
                element: this.el,
                container: Aurelia.container, // NOTE: I'm guessing here
                resources: Aurelia.resources, // NOTE: Same here, but I need all my global resources to be available inside the enhanced element too
                bindingContext: {} // NOTE: Not sure what to pass in here at all.. :/
            });
        }
    }
}

而我正在使用它:

<div aurelia-enhance.bind="exampleContent"></div>

其中exampleContent是从API调用获取的字符串,可能看起来像这样:'<my-custom-element></my-custom-element><button my-custom-attribute="some-value">Log in</button>'

javascript aurelia aurelia-binding
1个回答
2
投票

你走在正确的轨道上。有几件事需要考虑

  • bindingContext / overrideContext:这两个你可以通过挂钩到自定义属性的bind生命周期。因此,您将能够将它们传递给enhance指令(仅需要bindingContext,但传递两者更好,有助于遍历范围)。关于bindingContext,99%它将是你所在的视图模型,但你总是可以使用不同的对象。在这种情况下,this(自定义属性视图模型)是正确的。
  • 资源:取决于您希望TemplatingEngine.prototype.enhance返回的视图的资源范围。传递全局Aurelia实例的resources将不会产生它所驻留的自定义元素的本地资源范围。为了与属性注释的元素具有相同的资源,挂钩到属性的created生命周期,将第一个参数存储为owningView 。这是包含该属性的自定义元素的视图。然后你可以通过owningView.resources访问它的资源
  • 清理:TemplatingEngine.prototype.enhance返回一个View,你需要在你的属性生命周期中存储这个对detachedunbind的引用
  • 消毒

一个例子:https://gist.run/?id=9dd32bc8a772526ae527f593e26b275b

上面的要点是继承/增强的一个例子,我在话语中回答了另一个问题。您可以查看select-field以查看更多示例。它与你在那里做的很相似。

P / S:如果您对该解决方案感到满意,可以考虑撰写博客文章/文章,或者在Aurelia Discourse论坛上打开一个主题,以帮助其他人,他们也可能在那里挣扎。


更新示例:

import {Aurelia, inject, TemplatingEngine, DOM} from 'aurelia-framework';

@inject(Element, TemplatingEngine)
export class AureliaEnhanceCustomAttribute {
    constructor (el, aurelia, templatingEngine) {
        this.el = el;
        this.templatingEngine = templatingEngine;
    }

    // Custom attribute doesn't have its own view
    // Only the view of the custom element that owns it
    created(owningElementView, thisView) {
        this.owningElementView = owningElementView;
    }

    bind(bindingContext, overrideContext) {
        this.bindingContext = bindingContext;
        this.overrideContext = overrideContext;
    }

    attached () {
        this.el.innerHTML = this.value;

        // NOTE: Without checking for this we get an endless loop of attached() calls

        if (!this.el.classList.contains('au-target')) {
            this.dynamicView = this. this.templatingEngine.enhance({
                element: this.el,
                // we have two choices here, either the container of owning element, or this attribute
                // Lets go with the element, since it propbably has everything we need
                container: this.owningElementView.container,
                // the resources has information about its parent,
                // So we just need the resources of the element containing this attribute
                resources: this.owningElementView.resources,
                // Or this.bindingContext (same)
                bindingContext: this,
                // this helps travel up
                overrideContext: this.overrideContext
            });
        }
    }

    detached() {
        this.dynamicView.detached();
    }

    unbind() {
        if (this.dynamicView) {
            this.dynamicView.unbind();
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.