Accessing publish properties in the ready : function - polymer

How can I access the published properties in the ready : function of my custom element. I can get it if someone passes it in, but I want to check agains the default value. I.e.:
Polymer('post-card', {
publish: {
inline : false
},
ready:function(){
// returns what's passed in
var passedIn = this.getAttribute('inline'),
// returns null when inline is not present on the element
default = this.getAttribute('inline') ;
}
});
I know the default variable is looking for the attribute "inline" on the elemnt. My question is, how to I access the default value I set under the publish object?
Thanks in advanced :)

95% of the time, you should never need getAttribute when using polymer and published properties. Published properties are accessed as properties on this. In the context of your element, this is the element. To check against a default value, you could do something like this:
(function() {
var INLINE_DEFAULT = false;
Polymer('post-card', {
publish: {
inline: INLINE_DEFAULT
},
ready: function() {
console.log(this.inline === INLINE_DEFAULT);
}
}
}();

Related

Cannot update global variable within addeventListener function

Basically when running addEventListener I cannot access any of my saved variables from outside the function I am creating.
In the following code I always get the error Property 'xAxisLabel' does not exist on type 'HTMLElement'.
xAxisLabel:string = 'xAxis';
xAxisField:HTMLElement;
filterChanged(element: HTMLElement) {
element.addEventListener("change", function(){
this.xAxisLabel = 'Countries';
});
}
ngOnInit() {
this.xAxisField=document.getElementById('xAxisField');
this.filterChanged(this.xAxisField);
}
I am sure it's a fairly simple solution but I haven't been able to find it online. Any help would be appreciated.
It is due to 'this' keyword binding. You need to change your code to use arrow function, so:
filterChanged(element: HTMLElement) {
element.addEventListener("change", () => {
this.xAxisLabel = 'Countries';
});
}
now this.xAxisLabel refers to correct value

Polymer 2.0 :Please Explain the how the Observer method is working in this code?

This is the code snippet but I'm not able to understand how the observer method is working
static get properties() {
return {
selected: {
type: Object,
observer: '_selectedChanged'
}
};
}
_selectedChanged(selected, oldSelected) {
if (oldSelected) oldSelected.removeAttribute('selected');
if (selected) selected.setAttribute('selected', '');
}
connectedCallback() {
super.connectedCallback();
this.selected = this.firstElementChild;
}
full code: https://codelabs.developers.google.com/codelabs/polymer-2-carousel/index.html?index=..%2F..%2Findex#3
What is selected and oldselected and how can we do oldSelected.removerAttribute?
Are these objects of elements?
Please elaborate!
selected is property of element. It's value is some HTML element (in this case it's always img i think) so, in selected property there is always saved reference to img somewhere in html. When this property change, function _selectedChanged is called with 2 arguments. first argument is new image that is currently saved in selected and second argument is old image(previous value of selected).
further in tutorial you can see code
const elem = this.selected.nextElementSibling;
if (elem) {
this.selected = elem;
}
where is shown that const elem takes some html element and put it into this.selected.
So inside function _selectedChanged they removed html attribute from old image that was previously selected (so it was visible on screen) and added new html attribute to new image that should be visible on screen for now.
You can imagine that img with attribute selected is the only one that is shown on the screen at the time
I hope you understand my explanation. My english isn't 100% so if you have question, ask me and i can try to explain it more.
EDIT
Some example with binding and observer:
Let's say we have some paper-input which should show some results (articles for example) based on value of this input. So we have some HTML:
<paper-input value="{{search}}" label="Find articles"></paper-input>
this is primitive. Just some paper-input with value stored in search property. inside script tag:
Polymer({
is: 'test-el',
properties: {
search: {
type: String,
observer: "_findResults"
},
articles: {
type: Array
}
},
_findResults() {
this.set("articles", ['firstArticle', 'secondArticle', Math.random()]);
},
});
Explain: we defined property search and articles. Whenever property search changes, it calls function _findResults (because of observer). Function _findResults do only one thing. this.set("articles") is almost same as this.articles =. More about this can be found in documentation. So this.set("articles", ['firstArticle', 'secondArticle', Math.random()]); means it creates array and set it to articles property. and now, when we have some array that is changing everytime user enter some value in paper-input, we can add some HTML to show these articles:
<template is="dom-repeat" items="{{articles}}" as="item">
[[item]] <br>
</template>
I made also fiddle, so you can play with it and understand it a little bit more.
https://jsfiddle.net/2va41sy0/1/
Your question at the beginning was almost same in difference that they stored in some property reference to HTML object and not only just string. This is also about understand some basics of javascript and not polymer

Polymer. Way to dynamically add or remove observer

Is there a way to add or remove observer not in the moment of element initing?
I can define observer this way:
observers: ['dataChanged(data.*)']
Can i remove this observer later or can I set this observer different way than that?
You can easily add an observer dynamically, either by:
this._addObserverEffect("property", observerFunction);
or
this._addComplexObserverEffect("dataChanged(data.*)");
Removing is harder and Polymer does not provide a function to do this. Although you could search for it in the _propertyEffects array, I wouldn't recommend it. Maybe just check in your observer function whether it should still be active, and return if not.
you maybe can try this way:
configure your data property in the element with notify: true, so you can add a listener to changes with plain js
var element=document.querySelector("#YOUR-ELE-ID");
element.addEventListener("data-changed", function(e) {
//triggered when data property changes
});
https://www.polymer-project.org/1.0/docs/devguide/properties#notify
and to remove the bound listener you can call removeEventListener
https://developer.mozilla.org/de/docs/Web/API/EventTarget/removeEventListener
Example 1 - plain JS :
document.addEventListener('WebComponentsReady', function(e) {
var element=document.querySelector("#YOUR-ELE-ID");
element.addEventListener("data-changed", function(e) {
//triggered when data property changes
});
});
Example 2 - in custom element:
//...element definition...
ready: function() {
var element=document.querySelector("#YOUR-ELE-ID");
element.addEventListener("data-changed", function(e) {
//triggered when data property changes
});
}

Sammy.js : Partial calling/rendering my html twice

I am new to knockout and sammy. I am implementing SPA using Sammy(router) and KnockOut(binding).
I have below code.
this.get('#/Page/:operation', function (context) {
this.partial('templates/Page1.html', { cache: false }).then(function (content) {
// the first argument to then is the content of the
// prev operation
$('#sammyDiv').html(content);
});
});
When I checked the console it's saying "You cannot apply bindings multiple times to the same element.(…)".
Am I doing anything wrong here?
What's the difference between Partial and Render?
Im guessing you are injecting new html into the parent which has already been bound. You should either be more specific about which divs you are binding too. I.E on apply bindings to the parent div of the html you injected, or clean and reapply bindings. I use both methods throughout my application.
if (isBound("my-div"))
ko.cleanNode(document.getElementById('my-div'));
ko.applyBindings(myModel, document.getElementById('my-div'));
Helper Function:
// Checks if Element has Already been Bound (Stops Errors Occuring if already bound as element can't be bound multiple times)
var isBound = function (id) {
if (document.getElementById(id) != null)
return !!ko.dataFor(document.getElementById(id));
else
return false;
};
I use this check before all my bindings as a safety net.
Thanks for the response and comments. Issue was with Sammy router.
this.get('#/Page/:operation', function (context) {
this.partial('templates/Page1.html', { cache: false }).then(function (content) {
// the first argument to then is the content of the
// prev operation
$('#sammyDiv').html(content);
});
});
changed to
this.get('#/Page/:operation', function (context) {
this.partial('templates/Page1.html', { cache: false });
});
It worked perfectly fine. Thanks again.

HTML5 Contenteditable field and knockout: event rises before value binding [duplicate]

How can I bind an observable to an editable div text content?
You will need to modify the default "text" binding so that it is able to write the content of the edited div back to the observable. A simple custom binding handler for this task can look like this:
ko.bindingHandlers.editableText = {
init: function(element, valueAccessor) {
$(element).on('blur', function() {
var observable = valueAccessor();
observable( $(this).text() );
});
},
update: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
$(element).text(value);
}
};
But please note that this example code requires jQuery.
Usage is as simple as this:
<div contentEditable="true" data-bind="editableText: foo"></div>
Here is an example (written in CoffeeScript): http://jsfiddle.net/aBUEu/1/
You can't do that by default, because changing text in editable div won't raise any event that would update the value in your model.
You will need a custom binding for this. You can read about it here: http://knockoutjs.com/documentation/custom-bindings.html