Looking for the "Angular way". Using Angular 7 but if you know the approach in a different version that would be very helpful as well. New to Angular but not new to Javascript or programming.
I have a lot of text and I will most likely need to use some form of pagination but I am not there yet. I want to turn each word into a link. The text does change and will come from a server
Example of text received:
Bacon ipsum dolor amet hamburger cow short loin, pancetta ham venison chislic buffalo filet mignon turducken short ribs pork chop landjaeger tongue burgdoggen. Turducken pork chop pork belly sausage strip steak pork buffalo chuck cow short ribs pastrami. Spare ribs kielbasa swine ball tip. Pork belly fatback jerky boudin corned beef. Beef ribs flank pork, pork chop spare ribs cupim tenderloin pork belly ham hock tri-tip.
Example of generated html that needs to "compiled" into angular:
<span (click)='onClick("Bacon")'>Bacon</span> <span (click)='onClick("ipsum")'>ipsum</span> <span (click)='onClick("dolor")'>dolor</span> <span (click)='onClick("amet")'>amet</span> <span (click)='onClick("hamburger")'>hamburger</span> <span (click)='onClick("cow")'>cow</span> <span (click)='onClick("short")'>short</span> <span (click)='onClick("loin")'>loin</span>, <span (click)='onClick("pancetta")'>pancetta</span> <span (click)='onClick("ham")'>ham</span> <span (click)='onClick("venison")'>venison</span> <span (click)='onClick("chislic")'>chislic</span> <span (click)='onClick("buffalo")'>buffalo</span> <span (click)='onClick("filet")'>filet</span> <span (click)='onClick("mignon")'>mignon</span> <span (click)='onClick("turducken")'>turducken</span> <span (click)='onClick("short")'>short</span> <span (click)='onClick("ribs")'>ribs</span> <span (click)='onClick("pork")'>pork</span> <span (click)='onClick("chop")'>chop</span> <span (click)='onClick("landjaeger")'>landjaeger</span> <span (click)='onClick("tongue")'>tongue</span> <span (click)='onClick("burgdoggen")'>burgdoggen</span>. <span (click)='onClick("Turducken")'>Turducken</span> <span (click)='onClick("pork")'>pork</span> <span (click)='onClick("chop")'>chop</span> <span (click)='onClick("pork")'>pork</span> <span (click)='onClick("belly")'>belly</span> <span (click)='onClick("sausage")'>sausage</span> <span (click)='onClick("strip")'>strip</span> <span (click)='onClick("steak")'>steak</span> <span (click)='onClick("pork")'>pork</span> <span (click)='onClick("buffalo")'>buffalo</span> <span (click)='onClick("chuck")'>chuck</span> <span (click)='onClick("cow")'>cow</span> <span (click)='onClick("short")'>short</span> <span (click)='onClick("ribs")'>ribs</span> <span (click)='onClick("pastrami")'>pastrami</span>. <span (click)='onClick("Spare")'>Spare</span> <span (click)='onClick("ribs")'>ribs</span> <span (click)='onClick("kielbasa")'>kielbasa</span> <span (click)='onClick("swine")'>swine</span> <span (click)='onClick("ball")'>ball</span> <span (click)='onClick("tip")'>tip</span>. <span (click)='onClick("Pork")'>Pork</span> <span (click)='onClick("belly")'>belly</span> <span (click)='onClick("fatback")'>fatback</span> <span (click)='onClick("jerky")'>jerky</span> <span (click)='onClick("boudin")'>boudin</span> <span (click)='onClick("corned")'>corned</span> <span (click)='onClick("beef")'>beef</span>. <span (click)='onClick("Beef")'>Beef</span> <span (click)='onClick("ribs")'>ribs</span> <span (click)='onClick("flank")'>flank</span> <span (click)='onClick("pork")'>pork</span>, <span (click)='onClick("pork")'>pork</span> <span (click)='onClick("chop")'>chop</span> <span (click)='onClick("spare")'>spare</span> <span (click)='onClick("ribs")'>ribs</span> <span (click)='onClick("cupim")'>cupim</span> <span (click)='onClick("tenderloin")'>tenderloin</span> <span (click)='onClick("pork")'>pork</span> <span (click)='onClick("belly")'>belly</span> <span (click)='onClick("ham")'>ham</span> <span (click)='onClick("hock")'>hock</span> <span (click)='onClick("tri")'>tri</span>-<span (click)='onClick("tip")'>tip</span>.
I can do this in vanilla js but I guess I am having some issue with HTML binding? I read a few blogs that said Angular pipes are not efficient for large amounts of things and I do have a rather large amount of things. Not sure it matters but my text is unicode (not English). Whitespace within the text must be preserved. On the click, I do need a few things to happen with other static functions/components
Code is good but just pointing me in the right directions with some keywords or concepts is definitely enough.
I feel like the top solution here might be an option but the answer is 2 years old: Compile dynamic HTML in Angular 4/5- something similar to $compile in Angular JS
edit... this is where I'm at with the code. RIP formatting. The MessageComponent
does work. But now I need to figure out how to dynamically add a million view containers, I guess
//import { Component } from "@angular/core";
import { DomSanitizer } from '@angular/platform-browser';
import { Component, Input } from '@angular/core';
import {
Component,
ViewChild,
ViewContainerRef,
ComponentFactoryResolver,
ComponentRef,
ComponentFactory
} from '@angular/core';
//import { MessageComponent } from './message.component';
@Component({
selector: 'app-word',
template: "<span (click)='onClickMsg(message)'>{{message}}</span>"
})
export class MessageComponent {
@Input() message: string;
onClickMsg(msg: any) {
alert("msg="+msg);
}
}
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
@ViewChild('messagecontainer', { read: ViewContainerRef }) entry: ViewContainerRef;
title = "CodeSandbox";
textMap;
text = `
Bacon ipsum dolor amet hamburger cow short loin, pancetta ham venison chislic buffalo filet mignon turducken short ribs pork chop landjaeger tongue burgdoggen. Turducken pork chop pork belly sausage strip steak pork buffalo chuck cow short ribs pastrami. Spare ribs kielbasa swine ball tip. Pork belly fatback jerky boudin corned beef. Beef ribs flank pork, pork chop spare ribs cupim tenderloin pork belly ham hock tri-tip.
`;
constructor(private sanitized: DomSanitizer,
private resolver: ComponentFactoryResolver) {
};
componentRef: any;
createComponent(message) {
this.entry.clear();
const factory = this.resolver.resolveComponentFactory(MessageComponent);
const componentRef = this.entry.createComponent(factory);
componentRef.instance.message = message;
}
ngOnInit() {
this.textMap = this.textToDict();
this.createComponent("m");
}
textToDict() {
// var url = this.text.replace(/\w+/ug, function(word) {
// if (word.match(/\s+/)) return word;
// console.log("word=", word);
// var x = ''.concat('<button (click)=\'onClick("',word,'")\'>',word,'</button>');
// return x ;
// });
// return this.sanitized.bypassSecurityTrustHtml(url) ;
}
destroyComponent() {
this.componentRef.destroy();
}
}
edit 2...
this works enough it might be the start of a possible solution
ngOnInit() {
this.textMap = this.textToDict();
this.createComponent("m");
this.createComponent(" f");
}