繁体   English   中英

与用户创建的内容进行数据绑定/交互

[英]Databinding/interaction with user created content

我的最终目标是让用户创建的 HTML(来自数据库)能够在 Angular SPA 中导航。 从后端显示 HTML 的简单方法是使用DomSanitizer,然后绑定到某个元素的innerHTML 当用户创建的内容中的锚标记<a href="/path/to/diffrent/page/in/app">重新启动应用程序时,就会出现问题。 我想到了 3 个解决方案,它们都有问题。

注意:我想充分利用 AOT 和构建优化器。

  1. (带有 JIT 编译器的动态组件)
    用户创建的内容将具有像<a [routerLink]="/path/to/diffrent/page/in/app">这样的有角度的语法。 然后使用此处使用JitCompilerFactory和自定义装饰器加载运行时编译器的JitCompilerFactory ,以保留组件和模块元数据,以使用用户创建的内容作为模板进行 JIT 编译组件。 但是对于构建优化器,这需要恢复 ctorParameters 有了这个,你没有得到AOT的所有尺寸的好处,因为你仍然需要加载JIT编译器和说明在这里- “它似乎是有风险的编译器是受内部改变它为@角/编译@。 4.4.5 但可能不适用于其他版本。”

  2. (DOM 操作)
    在用户创建的内容<a href="/path/to/diffrent/page/in/app">保留适当的 HTML。 然后在绑定到innerHTML获得一个ElementRef ,然后找到每个锚标记并覆盖点击事件。 这种 DOM 操作在 angular 中似乎很不受欢迎。

  3. (自定义窗口事件)
    用户创建的内容看起来像<a onclick="window.someGlobalFunc("/path/to/diffrent/page/in/app")"> 然后以某种方式收听 angular 的窗口事件。 我更不喜欢这个想法,因为它完全在角度之外。

编辑添加:

  1. (监听容器“click”事件并过滤它是否来自锚点)
    见@cyrix 的回答

实现此功能的正确方法是什么?

编辑更新:
我接受了一个答案作为“最佳”选项,但如果有人找到或他们发布了“Angular”方式来做到这一点,请添加一个答案。

我遇到了同样的问题,并通过创建自定义指令并检查每次点击是否目标是锚元素来向动态内容的容器添加一个click侦听器来解决它。 如果它是一个锚元素,防止默认行为并采用href属性,请将其用作router.navigateByUrl url。

private onClick(e: any) {
    let link = this.checkForParentLink(e.target as HTMLElement);
    if(link && link.getAttribute('href')) {
      let href = link.getAttribute('href');
      let isMailOrPhone = href.startsWith('mailto:') || href.startsWith('tel:');
      if(isMailOrPhone) return;
      e.preventDefault();
      if(link.getAttribute('target') === '_blank') {     
        let win = window.open(href, '_blank');
        win && win.focus();
      } else {
        this.router.navigateByUrl(href);
      }
    }
  }

  private checkForParentLink(element: HTMLElement): HTMLLinkElement {
    if(!element) return;
    if(element.tagName === 'A') {
      return element as HTMLLinkElement;
    // this.element.nativeElement is in this case the container element
    }
    if(element.parentNode === this.element.nativeElement) {
      return null;
    }
    return this.checkForParentLink(element.parentNode as HTMLElement);
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM