In dart we can obtain dom element through 'querySelector' method. But I need a reverse kind method: insert data into "dart component" element from Javascript. Is there a way to achieve that?
I have try:
html file:
<comp></comp>
<script>
document.getElementById('mydiv').text = "HELLO";
document.getElementById('myd').text = "HELLO";
</script>
dart component:
#Component (
selector: 'comp',
template: '<div #mydiv id="myd">12345</div>',
)
class ModelerComponent {
PS: I need that because my js library requires element id, and there is no option to port it.
Thanks to comments, I've solve the problem:
I place code which initializes JS library into ngOnInit() method of a component. So the js library is initialised right after an angular component.
Related
This question is somewhat similar to the one that reads the same but it is for Angular 2, How can I use/create dynamic template to compile dynamic Component with Angular 2 the solution presented there is archaic at this point and the methods there don't even exist now. So basically my questions is this.
I am loading HTML from a service, the HTML comes with links like this:
<a routerLink='/content' (click)="loadHTMLData(pageId)">
so to load this properly into a container in my view I need to create a component on the fly and set its templateHTML attribute also dynamically to the received HTML, so that the (click) events work.
My idea was to create this dynamic component so they have an event handler that would trigger an event (#Output) with a notification to be then captured by the host component which in turn would perform another call to the service that returns the HTML and would replace this component for a new one with the new loaded HTML and it would repeat the process for each time a link is pressed in the content.
I have setup the dynamic creation of the component according with the instructions in https://angular.io/guide/dynamic-component-loader, so now I have a dynamic component but I don't know how to load the HTML as its template and have it rendering correctly. (right now the template renders as a string literal)
I tried passing the HTML to a static template using [innerHTML] by first sanitizing it with settings to trust the content, but that didn't work either, the html and styles were interpreted but the links weren't working.
The most relevant code looks like this:
#Component({
selector: 'app-content-info',
templateUrl: './content-info.component.html',
styleUrls: ['./content-info.component.css']
})
export class ContentInfoComponent implements OnInit {
#Input() info: ContenInfo;
#ViewChild(ContentInfoDirective,{static:true}) cInfoD: ContentInfoDirective;
constructor(private componentFactoryResolver: ComponentFactoryResolver) { }
ngOnInit() {
this.loadComponent();
}
loadComponent() {
const Item = this.info;
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(Item.component);
const viewContainerRef = this.cInfoD.viewContainerRef;
viewContainerRef.clear();
const componentRef = viewContainerRef.createComponent(componentFactory);
(<AdComponent>componentRef.instance).data = Item.data;
}
}
I adapted this from the Angular documentation site (ad-banner.component.ts), but the standard documentation says nothing on how to add a template dynamically.
So basically what I need to know is how can I inject/insert the HTML template with its (click) events in this dynamic component in Angular 8 to make the events work?
The answer that works will be immediately marked as correct.
Svelte’s templating language is great, in that it looks like HTML. However, for highly dynamic content I need to be able to use the full power of JavaScript, not just #if and #each. For example, given a tree data structure, I want to generate hierarchical table headings. (Demo) In React most apps use JSX templates, but you can drop down to createElement if you need to. Is there a similar path for Svelte? Am I missing something obvious?
If you need access to the DOM node, you can:
Add bind:this={node} to get access to the DOM node:
<script>
import {onMount} from 'svelte'
let node
onMount(() => {
const dynamic = document.createElement('a')
dynamic.innerHTML = "Click me!"
node.appendChild(dynamic)
})
</script>
<div bind:this={node}/>
Add a use directive, this will also get you access to the raw DOM node
<script>
function ninja(node) {
node.innerHTML = "Kawabunga!"
}
</script>
<div use:ninja/>
I would look at the <svelte:self> element, which allows you to create elements that call themselves recursively.
https://svelte.dev/tutorial/svelte-self
I am trying to clean up all jQuery related things in my application. While I was doing that I was in a confusion to use between javascript methods and angular native methods. So I need some clarifications for my below codes.
With jQuery to add and remove class dynamically:
$('.my-class').removeClass('list-hide').addClass('list-show');
In Javascript:
var element = document.getElementByClassName('.my-class');
element.classList.remove('list-hide');
element.classList.add('list-show');
Using TypeScript:
const element = this.elemRef.nativeElement.querySelector('.my-class');
element.classList.remove('list-hide');
element.classList.add('list-show');
The thing is I have many scenarios as above to access by DOM Id's and class names. And If I go by ElementRef I may end up in writing this.elementRef.nativeElement many times.
Also In the official documentation it is said that - ' if direct access to native elements is not supported, use Render2' with a caution notice.
So kindly help me with better ways to access DOM elements without more repetition and jQuery from my Angular application.
As far I understand going with ngClass would be easier for dynamically adding and removing class.
If you are targeting to a particular class and want to perform add or remove class dynamically, you could do something like below:
In ts:
filterBy:string = '';
selectedItemCode(field){
this.filterBy = field;
}
In html:
<div (click)="selectedItemCode('random1')">Example-One</div>
<div (click)="selectedItemCode('random2')">Example-two</div>
<section class="my-class" [ngClass]="filterBy === 'random1'? 'list-show' : 'list-hide'">
</section>
And to answer the question related to repetition of elemRef.nativeElement.querySelector('my-class'):
use a ngAfterViewInit life cycle hook like below:
export class SomeComponent {
public element;
constructor(private elemRef: ElementRef){}
ngAfterViewInit(){
this.element = this.elemRef.nativeElement;
}
}
After this you can use this.element.querySelector directly to access DOM elements
I am writing an app for angular 2 with ES5.
I want to have a component with dynamically loaded view child, that will load existing components.
I saw examples in TypeScript but I am failing do that in ES5, and to inject ng.core.ViewChild in component constructor based on a ng.core.Directive and update the contents of the DOM element ( marked with that directive) with a dynamically loaded, existent, component.
I've tried with
queries:[
formBody: ng.core.ViewChild('formBody')
]
...and I get a ElementRef, but would need a ViewContainerRef to update DOM contents with a dynamically loaded component.
I've tried :
queries:[
formBody: ng.core.ViewChild(app.FormBodyDirective)
]
... but I get a "empty" object. __proto__ object
Component is loaded like this:
ngAfterViewInit: function() {
var dialogComponentFactory = this.componentResolver.resolveComponentFactory(app.FormBody1_Component);
this.formBody = this.formBody.createComponent(dialogComponentFactory);
},
I have tried to inject ng.core.ViewContainerRef into component constructor:
.Class({
constructor: [
ng.core.ViewContainerRef,
function(viewContainer){
this.formBody = viewContainer
}],
but this of course injects a instance of ng.core.ViewContainerRef for my 'qform' element, and I get the dynamically loaded component at the end of the 'qform' element
Link to plunker with my code (not working) http://plnkr.co/edit/mRxGKYvKy8tHRjupNzju?p=preview
I would be very grateful if someone would help me sort this out, or throw a hint..
Thanks !
I finally find a solution. I am not sure that this is the best and most elegant way, but it works.
I injected ng.core.ViewContainerRef, in directive constructor and saved it's instance into class member.
The directive class member was accessible from within component. It was made available through component's queries option.
The directive:
app.FormBodyDirective =
ng.core.Directive({
selector: '[formBody]'
}).Class({
constructor: [
ng.core.ViewContainerRef,
function(viewContainer){
this._viewContainer = viewContainer;
}]
});
The component:
//...
queries : {
formBody: new ng.core.ViewChild(app.FormBodyDirective)
},
directives:[ app.FormBodyDirective ]
//...
Working plunker: http://plnkr.co/edit/ooWhiMqSFDtGNGdW3LMK?p=preview
Knockout gives you two ways of instantiating a component, either with a custom html element or with the component binding.
However I have discovered a slight issue when trying to style the root component element. It's fine if you just use the custom element syntax as you can just assign css styles to that - however, if you then use the component binding, the css rules don't match and so they fail.
Ideally I want to support both scenarios as they both have their uses. If I could get knockout to add a class to the root component element which is just the component name it would solve the issue but reading the documentation it isn't clear where it would be best to do this.
I've already got a custom template loader which retrieves the template from an ajax call, but this template is just the inner html of the root node.
Basically I want this:
<my-custom-element>
...
...
<my-custom-element>
To become this:
<my-custom-element class="my-custom-element">
...
...
<my-custom-element>
Anyone got any ideas?
You can use "createViewModel" method and access element in the component (e.g. to add some class):
ko.components.register('some-component', {
viewModel: {
createViewModel: function(params, componentInfo) {
var $element = $(componentInfo.element.children[0]);
// some other code ...
}
},
template: "<div></div>"
});