I am new to polymer and keep seeing the "is" property, but never get a thorough explanation of it. Example :
<script>
Polymer({is: "some-property"})
</script>
or
<template is="dom-repeat"></template>
It seems to be a declaration of inheritance or the like and i sorta get it but would like to find a clear explanation.
Per the documentation:
To register a custom element, use the Polymer function, and pass in
the prototype for the new element. The prototype must have an is
property that specifies the HTML tag name for your custom element.
In this case, the
<template is="dom-repeat"></template>
is a specific custom element built-in to Polymer.js, which extends the native HTML template element.
Related
I was looking at some Polymer code (link) and stumbled upon something new to me: a dollar sign $ in an html attribute name e.g.
<div class="item" wide-layout$="{{wide}}">
Also, a CSS selector is used:
.item[wide-layout] .title { ... }
How is the $ sign interpreted in the element attribute ?
Thanks for your time folks!
Using $ on the element binds a property to an attribute. You can read more here.
wide in your scenario is probably a Boolean property on the element.
When wide = true, a wide-layout DOM attribute will be added to the element so it can be targeted via CSS.
The dollar sign tells Polymer that some code will change the attribute, may it be class or any specific property on a Polymer element.
The code can be a function or a simple variable.
Example:
<shopping-cart class$="[[colorDependingOnItem(onSale, typeOfBrand)]] row-element">
So the class can now change dynamically depending on what the method colorDependingOnItem returns, based on the two properties onSale and typeOfBrand.
I have a component1 selector that I called "app-component1".
#Component({
selector: 'app-component1',
templateUrl: './test-widget.component.html',
styleUrls: ['./test-widget.component.scss'] })
So to call the html of this component I usually use:
<app-component1></app-component1>
and it works perfectly fine.
Now from another component2 I have the following variable:
variableToBind = "<app-component1></app-component1>";
And In the html of component 2 I used the following:
<div [innerHtml]="varibableToBind"></div>
The html code binding isn't working. Is is possible to help me understand why and maybe help me find another alternative?
Thanks Everyone for the suggestions, I actually just find the answer to this:
This can't work because innerHtml is rendered AFTER Angular's compiled the templates. That means that it doesn't understand your selectors at this point of time.
If you guys want to load a component (or any content) dynamically, you should use *ngIf. It worked perfectly fine for me.
Angular sanitizes the HTML to prevent XSS attacks. You should find something like WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss). in your console output.
For further information, check out the documentation on property binding (esp. content security) and the security docs.
Depending on your use case, you need to choose another approach.
Your example code is not a valid approach as
1) html code cannot be bound to element property directly for security reason. ref: https://angular.io/guide/security#xss
2) There is no need to do property binding for HTML in your case. If you want to perform different logic inside AppComponent2, the best practice is to do property binding for the parameters that can customise component behaviours:
<div>
<app-component1 [prop1]="myVar1" [prop2]="myVar2"></app-component1>
</div>
and then you can customise it from the component properties instead of the component itself. This would make more sense.
If you really* need to pass HTML to component (for example if you have text with <br> tags or something like that), you can create custom Input like so:
export class YourComponent {
#Input() public htmlContent = '';
}
<div [innerHtml]="htmlDescription"></div>
And use it like so:
<your-component [htmlDescription]="textWithHtmlTags"></your-component>
* - for example if a string of text with basic HTML formatting tags (like <b>, <i> or even <br>) needs to be rendered.
In Angular, it is generally not recommended to bind a component selector using the [innerHTML] binding, because this can lead to security vulnerabilities. Instead, you should use Angular's template syntax and component structure to include components in your templates.
If you need to dynamically choose which component to include based on some condition, you can use the ngIf directive and the element to include a component only if a certain condition is met.
<ng-template [ngIf]="showMyComponent">
<my-component></my-component>
</ng-template>
What does the "is" attribute in Polymer stand for? I Googled about it but to no avail. From what I understand it is the identifier of the component, however I am not sure how it is related to "is". Is it an abbreviation of some sort?
The is attribute is not Polymer-specific but part of the web components spec, specifically the Custom Element part of the spec. It's how you extend native elements.
Source: http://w3c.github.io/webcomponents/spec/custom/#instantiating-custom-elements
The is-Attribute is used to extend native HTML elements:
MyInput = Polymer({
is: 'my-input',
extends: 'input',
...
});
and later on
<input is="my-input">
You can find the documentation here.
Question
Which method of placing the <script> tags is "best-practice?"
Inside the <dom-module>?
or
Outside the <dom-module>?
Also, please answer:
Why?
What is the source of your answer?
What downside risks are there by doing it the "wrong" way?
Polymer Starter Kit: OUTSIDE
In the Polymer Starter Kit, the my-list.html and my-greeting.html files place the <script> tag outside the <dom-module>.
Like this:
<dom-module>
<style>...</style>
<template>...</template>
<dom-module>
<script>...</script>
Other Experts: INSIDE
However, I have heard and seen several examples from Google employees and Google developers that suggest the <script> tags should go inside the <dom-module>.
Like this:
<dom-module>
<style>...</style>
<template>...</template>
<script>...</script>
<dom-module>
The correct answer is - it shouldn't matter. While the documentation is indeed as #Mowzer noted, this is just an example rather than a definition. At least some actual Polymer elements like e. g. iron-image have it outside dom-module.
The relationship between the dom-module and the object Polymer constructor defines is established through the 'is' property of the object passed to the Polymer constructor and the id attribute of the dom-module.
From Local DOM guide:
Give the <dom-module> an id attribute that matches its element’s is property and put a inside the <dom-module>. Polymer will automatically clone this template’s contents into the element’s local DOM.
As a side note, you can also successfully use <script src="external.js"></script> to separate the html from the JS - I'm just guessing this is one possible reason for this question. The only drawback to this (AFAIK) is that in this case a vulcanized version of your element will show incorrect (offset) code line numbers for JS errors.
Looks like <script> tags should go inside the <dom-module>.
Per this definition in the developer guide.
Element definition
<dom-module id="element-name">
<template>
<style>
/* CSS rules for your element */
</style>
<!-- local DOM for your element -->
<div>{{greeting}}</div> <!-- data bindings in local DOM -->
</template>
<script>
// element registration
Polymer({
is: "element-name",
// add properties and methods on the element's prototype
properties: {
// declare properties for the element's public API
greeting: {
type: String,
value: "Hello!"
}
}
});
</script>
</dom-module>
I have seen it a lot here and there, yet I could find any description or documentation about it!
Example:
<paper-input-decorator label="Your Name">
<input is="core-input">
</paper-input-decorator>
In 2020:
The is attribute is now part of HTML spec in the Custom Elements specification.
It follows the polymer spec and is documented for developers at mdn.
Only Edge still hasn't updated to include this spec but it its new chromium-based implementation, in 2020, its availability may become widespread.
In 2017:
There is no is attribute in HTML.
It is a proposed extension that appears in the Custom Elements specification (which evolved from the Polymer spec mentioned below).
It allows you to say that an existing, standard element is really a custom element.
<button is="fancy-button" disabled>Fancy button!</button>
… which allows for backwards compatibility. If custom elements are not supported by the browser (the spec is still a draft and has very limited browser support) then it will fall back to the default behaviour.
In 2014:
It is not HTML. It is an expando-attribute for Polymer custom elements.
If you used extends to create a Polymer element that derives from an existing DOM element (something other than HTMLElement), use the is syntax
It is part of the W3C Draft spec for Web Components' Custom Elements.
Latest Working Draft: http://www.w3.org/TR/custom-elements/#type-extension-semantics
Latest Editor's Draft: http://w3c.github.io/webcomponents/spec/custom/#type-extension-example
The is keyword is part of the W3C Draft spec for creating custom HTML elements with custom behavior.
In specific, is is used when extending a built-in element like <input>, <button> or <table>. For example, you could have a plastic-button element that extends <button> to provide some fancy animation when clicked.
You'd add the button to the page like this:
<button is="plastic-button">Click Me!</button>
Before you do this, you need to register plastic-button as a custom HTML element like this:
customElements.define("plastic-button", PlasticButton, { extends: "button" });
This references a PlasticButton Javascript class, which would look something like this:
class PlasticButton extends HTMLButtonElement {
constructor() {
super();
this.addEventListener("click", () => {
// Draw some fancy animation effects!
});
}
}
It'd be great if you could say <plastic-button>Click Me!</plastic-button> instead of <button is="plastic-button">Click Me!</button>, but that would create an HTMLElement with no special behavior.
If you are NOT extending a built-in HTML element like <button> and instead creating a new element that extends the generic HTMLElement, you can use the <plastic-button> syntax. But you won't get any of <button>'s behavior.
This is part of the W3C Draft spec for Web Components' Custom Elements:
http://www.w3.org/TR/custom-elements/#type-extension-semantics
You use the is attribute to markup a customized built-in element, a custom element that extends a built-in element.
There are two types of custom elements:
Autonomous custom elements are standalone — they don’t inherit from standard HTML elements. You use these on a page by literally writing them out as an HTML element. For example <popup-info>, or document.createElement("popup-info").
Customized built-in elements inherit from basic HTML elements. To create one of these, you have to specify which element they extend (as implied in the examples above), and they are used by writing out the basic element but specifying the name of the custom element in the is attribute (or property). For example <p is="word-count">, or document.createElement("p", { is: "word-count" }).
https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_custom_elements
It's part of web components spec for Custom Elements. So it's HTML.
Frameworks like Vue.js also supports is atribute in compliance with web components standard.