Угловой / машинописный текст с routerLink - PullRequest
0 голосов
/ 14 июля 2020

Обновленный вопрос для большей ясности :

Необходимо отображать некоторые тексты и ссылки как внутренние HTML (данные из службы / БД) в Angular HTML и когда пользователь щелкает, он должен go to Typescript и программно перемещается по router.navigate

Кроме того, как добавить DomSanitizer из @ ViewChild / ElementRef

Все примеры добавлены в код ниже

Вот обновленный код stackblitz

Как показано на скриншоте из angular .io, некоторые тексты и некоторые ссылки

введите описание изображения здесь

Ответы [ 2 ]

1 голос
/ 17 июля 2020

Извините, я не понял, что вы ответили на мой комментарий. Маршрутизация Angular не является вторичной, если вы не используете модули Angular, вы получите только приложение HTML / CSS / Typescript. вам нужен как минимум RouterModule для Angular, чтобы иметь возможность использовать маршрутизацию и, следовательно, делать то, что он должен делать с DOM.

Сначала:

  • Вы не импортируется RouterModule

    решение:

    imports: [ 
      BrowserModule, 
      FormsModule, 
      RouterModule.forRoot([])  // this one
    ]
    

Второй:

  • Вы не можете привязать события Angular через внутреннее HTML свойство

    исправление:

Используйте директиву @ViewChild, чтобы изменить свойство innerHTML и вручную привязать к событию click, поэтому измените в app.component.html с

<div id="box" [innerHTML]="shouldbedivcontent" ></div>

на

<div #box id="box"></div>

Теперь в свой app.component.ts добавьте свойство для хранения ссылки на этот элемент «коробки», чтобы вы могли позже внесите некоторые изменения в dom с ним:

  @ViewChild('box')  container: ElementRef;

Реализуйте AfterViewInit, этот хук - это то место, где вы действительно сможете обрабатывать свой контейнер, если вы попытаетесь использовать его, например, в OnInit вы получите undefined, потому что этого компонента html еще нет в dom.

export class AppComponent  implements AfterViewInit {

и

ngAfterViewInit() {
    this.container.nativeElement.innerHTML = this.shouldbedivcontent;
    this.container.nativeElement.addEventListener('click', 
      () => this.goto('bar')
    );
}

изменить shouldbedivcontent свойство y от:

'1) this is a click 
 <a (click)="goto("bar")">Click</a><br> 
 2)this is with routerlink 
 <a routerLink="" (click)="goto("bar")">Click</a><br> 
 3)This only works with href 
 <a href="goto/bar" title="bar">bar</a>&nbsp; and test'

до

'1) this is a click 
 <a id="link_1">Click</a><br> 
 2)this is with routerlink 
 <a [routerLink]="" (click)="goto(\'bar\')">Click</a><br> 
 3)This only works with href 
 <a href="goto/bar" title="bar">bar</a>&nbsp; and test'

И даже в этом случае вы все равно не получите стиль привязки по умолчанию, если не примените некоторые стили самостоятельно.

Третий

Вы не HTML дезинфицируете , что может быть опасно. подробнее здесь

МОЕ ПРЕДЛОЖЕНИЕ:

Похоже, вам предстоит много сделать и много почитать для кого-то, кто работает вместе с вами для что-то, что вы могли бы легко сделать, как в примере ниже!

Переместите свой html на app.component.html:

<div id="box">
  1) this is a click 
  <a (click)="goto('bar')">Click</a><br> 
  2)this is with routerlink 
  <a routerLink="" (click)="goto('bar')">Click</a><br> 
  3)This only works with href 
  <a href="goto/bar" title="bar">bar</a>&nbsp; and test
</div>

<p>Below is actual content</p>

Вы заметите, что теперь все работает, кроме привязки без routerLink или href, потому что это не ссылка.

EDIT:

Глядя на новый stackblitz, я предлагаю изменить подход, привязка к внутреннему HTML нормально при работе с простым текстом или даже с каким-то простым html, но не лучший выбор для привязки событий или маршрутизации logi c.

Angular Renderer2 предоставляет множество методов для динамического добавления элементов в ДОМ. Имея это в таблице, вам просто нужно немного усилий, чтобы взять этот простой html, который вы получаете от вашего бэкэнда, и превратить его во что-то вроде (вставьте это свойство в свой код, чтобы протестировать его по остальной части кода, приведенного ниже):

public jsonHTML = [
  {
    tagName: '',
    text: 'some text with click ',
    attributes: {
    }
  },
  {
    tagName: 'a',
    text: 'bar',
    attributes: {
      value: 'bar' // goto parameter
    }
  },
  {
    tagName: '',
    text: ' some more text with click ',
    attributes: {
    }
  },
  {
    tagName: 'a',
    text: 'foo',
    attributes: {
      value: 'foo' // goto parameter
    }
  }
]

Как только он у вас есть, будет проще создавать все эти элементы динамически:

это для кода в вашем Q1:

Inject Renderer2 с private r2: Renderer2

И замените связанный с Q1 код в перехвате AfterViewInit на:

const parent = this.r2.createElement('div');  // container div to our stuff

this.jsonHTML.forEach((element) => {
  const attributes = Object.keys(element.attributes);
  const el = element.tagName && this.r2.createElement(element.tagName);
  const text = this.r2.createText(element.text);

  if (!el) {  // when there's no tag to create we just create text directly into the div.
    this.r2.appendChild(
      parent,
      text
    );
  } else { // otherwise we create it inside <a></a>
    this.r2.appendChild(
      el,
      text
    );

    this.r2.appendChild(
      parent,
      el
    );
  }
  
  if (attributes.length > 0) {
    attributes.forEach((name) => {
      if (el) {
        this.r2.setAttribute(el, name, element.attributes[name]); // just the value attribute for now

       if (name === 'value') { 
          this.r2.listen(el, 'click', () => {
            this.goto(element.attributes[name]); // event binding with property "value" as parameter to navigate to
          })
        }
      } else {
        throw new Error('no html tag specified as element...');
      }
    })
  }
})

this.r2.appendChild(this.container.nativeElement, parent); // div added to the DOM

Не требуется html дезинфицирующее средство и не нужно использовать routerLink, либо просто введите Router и перейдите по маршруту, который вы хотеть! Внесите улучшения в код, чтобы он соответствовал вашим потребностям, это должно быть по крайней мере хорошей отправной точкой

Удачи!

1 голос
/ 17 июля 2020

У вас проблема css.

  1. <a href="something"></a> выглядит как ссылка
  2. <a [routerLink]="something"></a> выглядит как ссылка, потому что если вы проверите HTML, это фактически получает свойство href, потому что routerLink
  3. <a (click)="goTo()"></a> НЕ выглядит как ссылка, потому что нет href

Chrome и Safari пользовательские агенты по умолчанию css не будут стилизовать <a> без href (не подтверждено Firefox, но я уверен, что это вероятно). То же самое для таких фреймворков, как bootstrap.

Обновленный stackblitz с перемещением CSS в глобальный, а не в приложение. css https://stackblitz.com/edit/angular-ivy-kkgmkc?embed=1&file=src / styles. css

Это сделает все ссылки синими по умолчанию или -webkit-link, если этот браузер поддерживает. Он должен быть в вашем глобальном файле. css, если вы хотите, чтобы он работал во всем приложении.

a {
  color: rgb(0, 0, 238);
  color: -webkit-link;
  cursor: pointer;
  text-decoration: underline;
}
...