使用RouterLink动态添加元素

时间:2016-03-30 13:27:41

标签: javascript typescript angular angular2-routing

当我将锚元素放在像这样的角度2组件中的某个部分时,

<a [routerLink]="['/LoggedIn/Profile']">Static Link</a>
一切都运转良好。单击链接时,角度路由器将我路由到目标组件。

现在我想动态添加相同的链接。在我的应用程序的某处,我有一个&#34;通知组件&#34;,其唯一的责任是显示通知。

通知组件的行为如下:

  <div [innerHTML]="notification.content"></div>

其中notification.content是NotificationComponent类中的字符串变量,包含要显示的HTML。

notification.content变量可以包含类似

的内容
 <div>Click on this <a [routerLink]="['/LoggedIn/Profile']">Dynamic Link</a> please</div>

一切正常并显示在我的屏幕上,但是当我点击动态链接时没有任何反应?!

有没有办法让角度路由器使用这个动态添加的链接???

PS。我知道DynamicComponentLoader,但我真的需要一个更无限制的解决方案,我可以将各种HTML发送到我的通知组件,并提供各种不同的链接....

3 个答案:

答案 0 :(得分:4)

routerLink在内容已呈现后无法添加,但是您仍然可以实现所需的结果:

  1. 使用动态数据创建href并为其提供一个类:

    library(shiny)
    library(lavaan)
    
    ui <- fluidPage(
        titlePanel("Text Input"),
        sidebarLayout(
            sidebarPanel(
                textAreaInput(inputId = "text1", 
                          label = "Syntax"), 
                          value = "Enter formula"),
            mainPanel(
               verbatimTextOutput("text1"),
               verbatimTextOutput("regout")
            )
    )
    )
    
    server <- function(input, output, session) {
    
      formula <- reactive({
        tryCatch({
          as.formula(input$text1)
        }, error = function(e) NULL)
      })
     
      model <- reactive({
        if(!is.null(formula()))
        tryCatch({
            cfa(formula(), data = HolzingerSwineford1939)
          }, error = function(e) NULL)
        })
      
      results <- reactive({
        if(!is.null(model())){
          summary(model(), fit.measures = TRUE)
        }
      }) 
        
        output$regout <- renderPrint({
          results()
        })
    }
    shinyApp(ui = ui, server = server)
    
  2. 向app.component添加一个HostListener,以监听点击并使用路由器来 导航

    `<a class="routerlink" href="${someDynamicUrl}">${someDynamicValue}</a>`
    

    }

答案 1 :(得分:1)

routerLink是一个指令。不会为使用[innerHTML]添加的HTML创建指令和组件。 Angular不以任何方式处理此HTML。

推荐的方法是不使用[innerHTML],而是 DynamicComponentLoader ViewContainerRef.createComponent,将HTML包装在组件中并动态添加。

有关示例,请参阅Angular 2 dynamic tabs with user-click chosen components

答案 2 :(得分:0)

自角度9起,AOT是编译角度项目的默认建议方式。 与JIT不同,AOT在运行时不为编译器保留实例,这意味着您无法动态编译角度代码。 可以在角度9中禁用AOT,但是不建议这样做,因为捆绑包的尺寸会更大,应用程序的速度也会变慢。

我解决此问题的方法是在运行时使用渲染器api添加一个Click侦听器,以防止url的默认行为并调用有角路由器

import { Directive, ElementRef, OnDestroy, OnInit, Renderer2 } from '@angular/core';
import { Router } from '@angular/router';

@Directive({
  selector: '[hrefToRouterLink]'
})
export class HrefToRouterLinkDirective implements OnInit, OnDestroy {
  private _listeners: { destroy: () => void }[] = [];

  constructor(private _router: Router, 
  private _el: ElementRef, 
  private _renderer: Renderer2) {
  }

  ngOnInit() {
    // TODO how to guarantee this directive running after all other directives without setTimeout?
    setTimeout(() => {
      const links = this._el.nativeElement.querySelectorAll('a');
      links.forEach(link => {
        this._renderer.setAttribute(link, 'routerLink', link?.getAttribute('href'));
        const destroyListener = this._renderer.listen(link, 'click',
          (_event) => {
            _event.preventDefault();
            _event.stopPropagation();
            this._router.navigateByUrl(link?.getAttribute('href'));
          });
        this._listeners.push({ destroy: destroyListener });
      });
    }, 0);
  }

  ngOnDestroy(): void {
    this._listeners?.forEach(listener => listener.destroy());
    this._listeners = null;
  }

}

您可以在此处找到示例:https://stackblitz.com/edit/angular-dynamic-routerlink-2

显然,上述方法对JIT和AOT均适用,但是如果您仍在使用JIT并且想要动态编译组件(这可能有助于解决其他问题)。您可以在此处找到示例: https://stackblitz.com/edit/angular-dynamic-routerlink-1

已用资源:

https://stackoverflow.com/a/35082441/6209801

https://indepth.dev/here-is-what-you-need-to-know-about-dynamic-components-in-angular