Im having a little trouble with a Custom HTML Element when using it inside Angular.
When adding the custom html element like this:
<custom-element *ngIf="something == false"
application-name="CUSTOM_NAME"
another-attribute="SOME_LINK">
</custom-element>
I can see the element in the DOM just fine, and it has 2 attributes:
application-name and another-attribute
However, if I add another attribute called on-accept, I assume, that the third attribute is turned into an event, as I cannot see all 3 attributes in the DOM.
<custom-element *ngIf="something == false"
application-name="CUSTOM_NAME"
another-attribute="SOME_LINK"
on-accept="SOME_EVENT">
</custom-element>
when doing an ng-serve, it gives me this Error:
ERROR in src/app/components/main/main.component.html:5:118 - error TS2339: Property 'SOME_EVENT'
does not exist on type 'MainComponent'.
5 <custom-element *ngIf="something == false" application-name="CUSTOM_NAME" policy-link="SOME_LINK"
on-accept="SOME_EVENT" ></custom-element>
When I rename on-accept to onAccept it works just fine.
Note: I want to decouple my custom HTML element from Angular completely as I would also like to use it in other apps aswell. And I want to use an attribute called on-accept, but apparently i cannot use custom attribute on-accept on my custom element, when inside an Angular app...
This makes it non-reusable.
If I use my custom element in some plain HTML file, I get expected bahaviour, and it shows me an element with 3 custom attributes:
application-name, another-attribute and on-accept
Why can I not use an attribute called on-accept within my Angular App?
In angular templates: on-xy="..." is like (xy)="..." , so on-accept="yourMethod()" is like (accept)="yourMethod()"
Your "SOME_EVENT" should be an existing function in your component. Try this:
MainComponent:
onAcceptEvent(evt) { console.info(evt); }
Template:
<custom-element *ngIf="something == false" on-accept="onAcceptEvent($event)" ></custom-element>
Related
I have a reference to a textarea
<*wrapper-component (submit)="tx1.value ? submit(tx1.value) : tx1.setClass('required')??">
<textarea #tx1> <textarea>
</*wrapper-component>
which I pass the value of into my submit function, is it possible to set classes for my tx1 element from the HTML itself instead of creating a ViewChild property and accessing elRef.nativeElement.setClass with typeScript?
I'd normally suggest using [ngClass] binding for setting CSS selectors dynamically. However, if you insist on using a template ref variable, you could use the setAttribute() method to set attributes, in your case 'class'.
<*wrapper-component (submit)="tx1.value ? submit(tx1.value) : tx1.setAttribute('class', 'required')">
<textarea #tx1> <textarea>
</*wrapper-component>
for some reason, I cannot change the text of a span
This is the span in html
<span id="sortingText"></span>
This is the span being called within typescript
sortingText : any = document.getElementById("sortingText");
And this is the method where I am changing the value
this.sortingText.textContent = "Sorting by Descending";
However when I try this, I get "ERROR TypeError: Cannot set property 'textContent' of null"
What am I doing wrong?
As you're using Angular, why don't you use interpolation?
Add a property which contains the sort order:
sortingText = 'Sorting by Descending';
In your component's template:
<span>{{ sortingText }}</span>
To display the sort order, you have to put your property between two double braces, this way Angular will insert its value in your span.
You should read how to display data in Angular docs.
Your question is tagged with angular so inject elements like this:
How can I select an element in a component template?
I have a component in Vue component-z.
I need to pass in certain parameters, so when I use this in my Vue's html I do as follows:
<component-z id="component" data1="data" data2="moreData"></component-z>
I need to take the html out of this and pass it as a message to a parent frame (from an iFrame). Is there a way to do something like:
<component-z id="component" data1="data" data2="moreData"></component-z>.toHtml()
First, add a ref attribute to the line, such as ref='component-z'
If you are inside the <script> portion of the Vue file, you can access the Vue instance and its references like this:
this.$refs
To access the outer HTML (or rendered/raw HTML) of that component, use
this.$refs["component-z"].$el.outerHTML
Note the "component-z" portion of that JavaScript, which corresponds to that ref attribute you set.
I am new to Angular and have run into a problem that seems to have a javascript work around but they aren't very elegant.
I have a model with an array property. I ngfor the list property to build some html selection options. This is all working nicely. The problem comes when I am trying to set default value...the html elements don't have a load event.
I tried numerous html elements and they don't appear to have a load event either but I certainly could be doing it wrong.
I have seen a solution to put javascript tag right after the html and I could do that but I was really looking for a more elegant way in Angular.
I saw this SO post and thought that was my answer but there is a warning given that I agree with and thus it doesn't appear to be a good solution.
Regardless I tried it just to see if it would work and I got:
Failed to execute 'setAttribute' on 'Element': '{{loadDefaults()}}' is not a valid attribute name
<span {{loadDefaults()}} ></span>
So how can I fire an AS2 function in the component to load the default values?
HTML (btw this is NOT a full page load so there is no body tag):
<tr>
<td *ngFor="let loc of locOptions;">
<span>{{loc.text}}</span>
<input type="radio" name="radiogroup" [value]="loc.value" (change)="onSelectionChange(loc.value)">
</td>
</tr>
Edit
I thought perhaps mistakenly that ngoninit would fire too soon...before the html elements are rendered.
So perhaps what is being suggested is that I add a boolean is default to the model and bind THAT as the element is rendered.
In your ngonit function set this.locOptions to your default values. The value can be changed later on in any function and the change will be reflected in the view. Hope this helps you.
You should use ngOnInit to init you data, and call retrieve your data from your component :
defaults : any;
ngOnInit {
this.defaults = loadDefaults();
}
loadDefaults() {
//get data
}
HTML :
<span>{{defaults}}</span>
I got an error when i put a nested ng-show attributes for custom directive,
one attribute in the markup of the directive and the second inside the root element of the directive template.
My real scenario are complex so i will simplify it to this example:
Suppose i have my-custom-directive below which already contains ng-show:
<my-custom-directive ng-show="someValue >= 5"></my-custom-directive>
And then the template of 'my-custom-directive' look like this:
<div ng-show="options != null">My Custom Directive</div>
Those multiple ng-show together cause an error.
if i remove one of them or move the inner ng-show at least one level deeper in it's dom tree the error gone (it's happen when it's location is on the root template element).
this error tested on angular v1.4.8.
Is this angular bug? or there is a reasonable explanation for this behavior?
here is the Plunker example:
http://embed.plnkr.co/ZTZVcfc5bfmjPo9t0Isw
Thank you in advance,
Menachem
Because the directive has replace: trueit is trying to merge the two ng-show values together resulting in an error. The simplest solution I believe is to just do replace: false
Or you can inject the value via isolate scope and use a single ng-show value within the directive. I believe this is considered the cleaner solution.
Example: http://plnkr.co/edit/5oc8c1Hrz8N1F2klCio7?p=info
scope: {
someValue: '=someValue'
}