【问题标题】:How to dynamically enhance HTML with Aurelia如何使用 Aurelia 动态增强 HTML
【发布时间】:2017-12-30 15:26:54
【问题描述】:

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

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

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

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

我们如何克服这个问题?

编辑:使用来自@bigopon 的 cmets,我已经开始做一些事情,但仍然无法让它发挥作用。要么我不擅长搜索,要么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>'

【问题讨论】:

  • 使用 innerhtml 时,“解析”是什么意思?
  • 如果作者在他们的博客文章或页面中使用自定义属性或元素,它们不会被 Aurelia“解析”(也许是错误的词?),因此元素或属性永远不会运行。
  • 你需要的不是innerhtml,使用TemplatingEnginecompose/enhance函数,会有帮助的
  • 好的,你有机会用一个例子发布答案吗?
  • 这个周末或者今天晚些时候我应该可以写一篇了。如果对您来说很紧急,请查看 aurelia 对话框或在 aurelia 模板资源 repo 中撰写元素。

标签: javascript aurelia


【解决方案1】:

你在正确的轨道上。需要考虑的事情很少

  • bindingContext / overrideContext:这两个你可以通过挂钩到自定义属性的bind 生命周期来获得。因此,您将能够将它们传递给 enhance 指令(仅需要 bindingContext,但同时传递两者更好,有助于遍历范围)。关于bindingContext,99% 将是您所在的视图模型,但您始终可以使用不同的对象。在这种情况下,this(自定义属性视图模型)是正确的。

  • resources:取决于您希望TemplatingEngine.prototype.enhance 返回的视图的资源范围如何。传递全局Aurelia 实例的resources 将不会产生它所在的自定义元素的本地资源范围。为了与属性注释的元素具有相同的资源,挂钩到属性的created 生命周期,将第一个参数存储为owningView。这是包含该属性的自定义元素的视图。然后你可以通过owningView.resources

  • 访问它的资源
  • 清理:TemplatingEngine.prototype.enhance 返回一个View,你需要在你的属性生命周期中存储这个对detachedunbind 的引用

  • 消毒

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

上面的要点是我为回答 Discourse 上的另一个问题而制作的继承/增强示例。您可以查看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();
        }
    }
}

【讨论】:

  • 哦,伙计:P 这对我来说有点太复杂了哈哈:D 我真的很感谢你的帮助,但老实说,我不知道如何修改我的代码以使其基于该 Gist 工作。 ..抱歉有点菜鸟:P
  • 主要是关于select-field。在其附加的生命周期中,您可以看到增强功能是如何使用的。
  • 是的,我找到了该文件并查看了您如何使用 enhance() 方法,但没有文档,我仍然发现很难将该代码转换为对我有用的东西。您无法修改我的问题中的代码以使其正常工作?
  • 我刚刚更新了答案。我可能你必须做更多的事情,比如消毒,检查适当的时间和东西,但它可能会给你一些如何继续的想法。不过,请考虑发布您的解决方案以帮助他人:)
  • 非常感谢,我会尽快尝试
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-26
  • 2022-08-04
  • 1970-01-01
  • 1970-01-01
  • 2021-05-09
相关资源
最近更新 更多