Angular2 Динамический HTML с функциональным RouterLink

Долгое время пользователь, впервые задававший вопрос! Я пытался понять это в течение большей части двух дней безрезультатно, так что здесь мы идем.

Динамически скомпилированные шаблоны из внешних источников в Angular2?

Я использую http для получения содержимого страницы в виде HTML из WordPress API. Итак, у меня есть такой шаблон:

    

и "contentHTML" - строковая переменная в компоненте, которой присвоено значение асинхронно через вызов API для чего-то вроде этого:

     

и я хочу, чтобы routerLink работал. Конечно, routerLink может быть чем угодно в шаблоне.

Если вышесказанное невозможно

Если вышеперечисленное не сработает, как насчет способа интерпретировать входящий HTML и добавить routerLinks на лету, чтобы заменить стандартные hrefs?

3 ответа

Решение

Я столкнулся с той же проблемой, следовал этому ответу, но добавил простую модификацию в код, куда вы импортируете DynamicComponentModule, но добавил импорт: [RouterModule]

Таким образом, шаги будут следующие: install ng-dynamic:

npm install --save ng-dynamic

Затем используйте следующий импорт и код:

import { DynamicComponentModule } from 'ng-dynamic';

@NgModule({
   imports: [
       ...
       DynamicComponentModule.forRoot({imports: [RouterModule]}),
       ...
   ],
   ...
})
export class AppModule {} 

Тогда вместо:

<div [innerHTML]="contentHTML"> </div>

Использование:

<div *dynamicComponent="contentHTML"></div>

надеюсь это поможет!

Одним из возможных решений без использования динамической компиляции во время выполнения при использовании стратегии определения местоположения хэша является использование следующего HTML

<a onclick="window.location.reload()" href="#/pages/Home">Click</a>

где /pages/Home это угловой маршрут. Это будет установлено в div следующим образом

<ng-container *ngIf='content'>
  <div [innerHTML]="content.text"></div>
</ng-container>

Это вызовет перезагрузку в месте назначения, следовательно, передает вещи угловому маршрутизатору.

ОБНОВЛЕНИЕ 1

Я использовал аккуратный обходной путь для этого, используя пользовательские события. Я добавил пользовательский JS следующим образом

function navigate_in_primary(url) {
    var evt = new CustomEvent('content_navigate', { detail: { url: url, primary: true } });
    window.dispatchEvent(evt);
}

Я слушаю это событие, используя RxJs, в конструкторе пользовательского сервиса, внедренного в app.module

Observable.fromEvent<Event>(window, 'content_navigate')
.subscribe((event)=>{
    this.router.navigateByUrl(event.detail.url);
})

Наконец, мой HTML

<a onclick="navigate_in_primary('/pages/home.aspx')" class="grey-button">SIGN IN</a>

После долгих поисков я обнаружил, что ответ на Angular 2.1.0 создать дочерний компонент "на лету", динамически очень полезен для работы!

СЕКРЕТНЫЙ СОУС!!!

За подробностями ознакомьтесь с полным примером Plunker от yurzui, но в двух словах: убедитесь, что класс DynamicHtmlModule, который создает скомпилированный во время выполнения компонент, имеет ссылку на модуль RouterModule. В противном случае директивы routerLink, используемые в динамическом шаблоне, не будут работать. Я выделил ключевой фрагмент кода ниже.

@NgModule({
  imports: [CommonModule, <strong>RouterModule</strong>],
  declarations: [decoratedCmp]}) class DynamicHtmlModule { }

  return compiler.compileModuleAndAllComponentsAsync(DynamicHtmlModule)
   .then((moduleWithComponentFactory: ModuleWithComponentFactories<any>) => {
     return moduleWithComponentFactory.componentFactories
      .find(x => x.componentType === decoratedCmp);
  });
}

То же самое будет верно для любой другой директивы или компонента, который может использовать ваш шаблон. Вы должны убедиться, что ваш DynamicHtmlModule правильно ссылается на них, чтобы заставить их работать.

Другие вопросы по тегам