Polymer attribute directive - javascript

Is there any way to achieve angularjs attribute directive in polymer. I want to call a function based on a particular attribute attached to any element.
This is what works for me right now, but this is very non-generic.
Is there any easier way to extend behavior of elements using just attributes like
<paper-input behavior="custom-behavior" custom-behavior-attribute="some-data"></paper-input>

I have started building an app in Polymer which was already done in Angular. Even I had the same query running on my mind and I found this link related to this topic and it says Polymer's behavior is the equivalent to Angular's attribute directive.
https://plus.google.com/+JustinFagnani/posts/EjdR14bA7Dj
It will be useful if someone can confirm that there are no other approach available to achieve the same.

Related

How to parse a html string to native angular template

Currently I'm rendering the html string using innerHtml property after bypassing the angular sanitizing mechanism this is working for rendering the contents. But not able to map the event handlers to a function in angular component.
E.g.the html string will contain a button like below
<button (click)="callme()">Click</button>
the callme function will be part of angular component file. I want this click event to be handled in angular function.
Is it possible to parse this string to html dom and handle the events in angular components.
Sample code which describes this scenario and using angular cdk Portals.
https://stackblitz.com/edit/angular-upaudh?file=src%2Fapp%2Fcdk-portal-overview-example.ts
There are 2 ways that you can implement it, it depends from what you want.
The easy way is to use innerHtml input like this:
HTML
<div [innerHTML]="htmlStr"></div>
TS
htmlStr: 'Hello';
If you want to create a dynamic template that will be translated to HTML at build time. Then you have to go with Portals.
PS: In your example (in the comments) you use [innerHtml] and try to bind it in a Portal. Again [innerHtml] will not be translated before runtime so your click event will not be in the same scope as your component. The thing that you ask is an open conversation in github: Issue. For now you can use the alternatives above to solve your case. You can use innerHtml, and then use renderer2 or native element reference to bind click events to your functions, after they have rendered on the view.

How do property binding works with directives in angular?

So I understand how basic property binding works in angular for elements like input, but I came across some code that was using node module ng-drag-drop which comes with a set of its own custom directives. In html of a component there is a div element that uses one of the directives called droppable and property binding [dragOverClass]="'drag-target-border-green'" but DIV elements have no property like dragOverClass. So where does it come from? The directive? I was checking angular docs for data binding and it says nothing about this, just basic property binding chapter with input value examples. Thanks for the help.

Polymer - Load different components dynamically

I'm a Polymer novice, but I guess what the answer will be...
Recently I came across with this issue: I got to loop through a collection of elements (using dom-repeat) and display its contents. But every element has a unique display and bindings, making it almost impossible to display each element dynamically. The ideal scenario would be to load a different component for each display type, but it looks like there is no easy way to achieve this.
Some options I have been thinking of were the following:
Using dom-if but it would add crap to my resulting HTML.
Is there a dom-switch? If it were something like that and didn't leave empty template tags (as it would do with dom-if) it would be nice.
It's possible to load a component dynamically? Using something like this: <[[item.type]] item-configuration=[[item.configuration]]></[[item.type]]>
Any other ideas? I would really appreciate any ideas or solutions or at least a workaround for my issue.
TL;DR; you can't
Polymer (and Web Components in general I guess) are best when used in a declarative way. Out-of-the-box your best solution is dynamically creating elements and adding to DOM or messy use of dom-if.
(potential) OPTION 1
I guess you could fairly easily implement a dom-switch element to work like
<template-switch switch="[[some.value]]">
<template-case case="10">
<element-one></element-one>
</template-case>
<template-case case="20">
<element-two></element-two>
</template>
<template-default>
<element-one></element-one>
</template-default>
</dom-switch>
I wrote this off the top of my head. There are multiple ways to implement such an element. A crucial decision is whether to use <template> internally or not. In this plunk I've implemented such element without templates but simply using content distribution.
OPTION 2
There is also Polymer.Templatizer.
Faced with a similar issue of choosing element to render dynamically I created this Plunk as a proof of concept.
As you see, you extend the <template> element with custom rules, which match against a model. You then bind the matched template's nodes with the model using Polymer.Templatizer.
Thanks to Templatizer, you don't have to pollute your actual element with conditionals and still get full binding functionality.
I'm working on a more feature-complete solution. If you're interested I could move it to a separate repository and publish.

How to use ng-class in select with ng-options in Angular 1.4 and higher

My problem is similar to the one of the following post : How to use ng-class in select with ng-options
I want to be able to customize specific options in my select using CSS. If I resume the example used, I have an array of persons like this :
var persons = [
{Name:'John',Eligible:true},
{Name:'Mark',Eligible:true},
{Name:'Sam',Eligible:false},
{Name:'Edward',Eligible:false},
{Name:'Michael',Eligible:true}
];
Now I want to be able to write some code like the following to display differently one Elligible person to another not Elligible :
<select ng-model="Blah" ng-options="person.Name for person in persons" ng-class="{'is-elligible': person.Elligible}"></select>
But in this code, I don't have access to the person variable in the ng-class tag.
The thing is in the other post, the solution was based on a cutom directive which works well in angular before the 1.4. Now this solution doesn't work anymore.
A possible solution is also not to use ng-options but to use ng-repeat in an option tag. But I would like to still work with ng-options because it seems faster and easier to use.
So if anybody have any solution to do this with angular 1.4 and higher, it would be great to share it ! :)
Thanks in advance
You cannot do it with plain ng-options.
You should use ng-repeat or custom directive to achieve desired behaviour. In case if case such simple as you described i recommend you using ng-repeat as it's common approach to achieve that behaviour.
Consider diving into details of already existed answer:
Customize ng-options selection look and it would answer your question.
p.s. Didn't catch your point of using ng-repeat, because in particular case it's easier to use already existed directive than creating new one and adding unit tests to it, where you
've got idea that ng-repeat is slower...

Extended HTML attributes

I am a beginner in web development, and I have some misunderstanding.
From wwwschools:
AngularJS extends HTML with new attributes.
So angularJS uses for example ng-model, ng-app and so on.
My questions are
Why does AngularJS does this, when adding custom attributes makes the HTML invalid?
Can I add my own attribute like <h myAttr="hello"> and then access it with JS just like a normal attribute?
Angular doesn't add them by itself. It allows you to use some custom attributes, like ng-model to deal with its functional stuff, but you have to set them by yourself.
And if using non-standard attributes bothers you, you can replace them by data-* valid attributes, like data-ng-model="stuff".
Finally, adding your own custom attributes (generally called directives in Angular) is often use. You can check angular doc for a hint on how you can achieve this.
Why does AngularJS does this, when adding custom attributes makes the HTML invalid?
The idea is that you can write your own custom self-contained elements that better explain what their purpose is. For example, instead of:
<div class="date-picker" data-initial="2015-08-08"></div>
you can write:
<date-picker value="2015-08-08" />
which is more self-explanatory than a plain <div> with a special marker CSS class.
Of course this wouldn't just work out of the box, you would have to define this new date picker element by writing an Angular directive.
Can I add my own attribute like and then access it with JS just like a normal attribute?
Yes, you can, by writing a new directive (see above).

Categories

Resources