javascript - 与用户创建内容的数据绑定(bind)/交互

标签 javascript html angular angular-cli angular2-aot

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

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

  1. (带有 JIT 编译器的动态组件)
    用户创建的内容将具有 Angular 语法,如 <a [routerLink]="/path/to/diffrent/page/in/app"> .然后用例子here使用 JitCompilerFactory 加载运行时编译器自定义装饰器将组件和模块元数据保存到 JIT 编译组件,用户创建的内容作为模板。然而,对于构建优化器,这需要 restoring the ctorParameters .这样您就无法获得 AOT 的所有大小优势,因为您仍然需要加载 JIT 编译器并且如前所述 here ——” 这似乎是有风险的,因为编译器会受到内部变化的影响。它适用于@angular/compiler@4.4.5,但可能不适用于其他版本。”

  2. (DOM 操作)
    在用户创建的内容中保留适当的 HTML <a href="/path/to/diffrent/page/in/app"> .然后绑定(bind)到innerHTML之后得到一个ElementRef ,然后找到每个 anchor 标记并覆盖点击事件。这种 DOM 操作在 Angular 中似乎非常令人沮丧。

  3. (自定义窗口事件)
    用户创建的内容将类似于 <a onclick="window.someGlobalFunc("/path/to/diffrent/page/in/app")"> .然后以某种方式以 Angular 收听窗口事件。我更不喜欢这个想法,因为它完全不符合 Angular 。

编辑添加:

  1. (监听容器的“点击”事件,如果它来自 anchor 则进行过滤)
    参见@cyrix 的 answer

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

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

最佳答案

我遇到了同样的问题,通过创建自定义指令并检查每次点击是否目标是 anchor 元素,向动态内容的容器添加一个 click 监听器解决了这个问题。如果它是 anchor 元素,则阻止默认行为并采用 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);
  }

关于javascript - 与用户创建内容的数据绑定(bind)/交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46776359/

相关文章:

javascript - 为什么这个 http 服务器要这样做?

javascript - 使用 javascript 加载和读取本地文本文件的最简单方法?

javascript - 我正在 Pyramid 工作,但不知道如何将 POST 从服务器发送到网站,并使用 Ajax 捕获它

html - CSS3 - 如何在不添加 html 元素的情况下在行的中间添加不同的颜色

html - Div 标签和标题

typescript - Angular2 中多个类的 setElementClass

javascript - AngularJS UI Typeahead - 设置结果属性之一的样式

html - 960 网格系统 - 12 列 - 接触容器边缘

angular - 带有 AOT 编译器的 NGRX angular 5 reducer

css - 可滚动涡轮表中的 PrimeNG 过滤器下拉问题