Polymer one-way-binding not working - javascript

After hours of trying I'm clueless. Maybe some of you have the answer. I've create a Polymer template like this:
<dom>
</dom>
<script>
Polymer ({
is: 'foo',
proprties: {
timeRange: {
type: String,
value: 'day',
readOnly: true,
observer: "_refresh",
},
...
},
...
});
</script>
The observer function is just for debugging. The calling host uses this like that:
<dom>
<foo time-range='[[timeRange]]'></foo>
</dom>
<script>
Polymer ({
is: 'host',
proprties: {
timeRange: {
type: String,
value: 'day',
readOnly: true,
notify: true,
observer: "timeRangeChanged",
},
...
},
onDayTap: function() {
this._setTimeRange('day');
},
onMonthTap: function() {
this._setTimeRange('month');
},
onYearTap: function() {
this._setTimeRange('year');
},
...
});
</script>
The 'timeRangeChanged' observer refreshes a chart. But the timeRange-property in foo never gets changed - the _refresh-observer gets called only once on start. What am I doing wrong.
Hope somebody can help me out here
PS. I'm using Polymer 1.0
Hope this will help:
https://jsfiddle.net/fLbp26kp/

Polymer ({
is: 'foo',
properties: {
timeRange: {
type: String,
value: 'day'
observer: "_refresh",
}
}
});
If you're trying to update foo.timeRange you would need to remove readOnly from timeRange in order for it to be set from somewhere else.
Foo without readOnly.

Related

How to pass a function to component to handle a drag event

I want to use v-for and is to render the components I need. So I create the component Cube.vue like this:
<script>
export default {
name: 'cube',
render: function(createElement) {
return createElement("div",{
props: {
style: {
type: Object
},
dragstartHandler: {
type: Function
},
classNames: {
type: Array|String|Object
}
},
style: this.style,
attrs: {
draggable: "true",
},
on: {
dragstart: this.dragstartHandler
},
'class': this.classNames
},[
createElement("div",{
class: ["resizer", "top-left"]
}),
createElement("div",{
class: ["resizer", "top-right"]
}),
createElement("div",{
class: ["resizer", "bottom-left"]
}),
createElement("div",{
class: ["resizer", "bottom-right"]
}),
])
}
}
</script>
And then, I use it like this
<component
v-for="component in components"
:class="component.classes"
:key="component.refValue"
:is="component.type"
:style="component.style"
:dragstartHandler="component.dragstartHandler"
:ref="component.refValue"
>
</component>
Everything as I expected, except the dragstartHandler. It throws an error
[Vue warn]: Invalid handler for event "dragstart": got undefined
I try to console.log() the components. The result is :
[{…}, __ob__: Observer]
0:
classes: Array(2)
dragstartHandler: ƒ ()
refValue: "cube-0"
style: Object
type: "cube"
It really is a function. But I don't know why it go to undefined in the render. I have checked I didn't spell wrong.
I just want pass the function to the component to handle the drag event. So how does it happened and what should I do to resolve it.
The dragHandler function is these:
dragstartCopyHandler(event) {
event.dataTransfer.setData("elementId", event.target.id);
event.dataTransfer.setData("componentOffsetX", event.offsetX);
event.dataTransfer.setData("componnetOffsetY", event.offsetY);
event.dataTransfer.setData("dropEffect", "copy");
event.dataTransfer.dropEffect = "copy";
},
dragstartMoveHandler(event) {
console.log("move start")
event.dataTransfer.setData("elementId", event.target.id);
event.dataTransfer.setData("componentOffsetX", event.offsetX);
event.dataTransfer.setData("componnetOffsetY", event.offsetY);
event.dataTransfer.setData("dropEffect", "move");
event.dataTransfer.dropEffect = "move";
},
And I pass the dragstartMoveHandler to the component.
this.components.push({
refValue: `${elementId}-${this.count}`,
type: elementId,
style: style,
dragstartHandler: this.dragstartMoveHandler,
classes: ["component", elementId]
});
I write the pages use js to control Dom before. And today I want to rewrite it with vue. So here might something wrong with the function, but the problem now is the function passed is undefined.
The cube component needs to define a prop for dragstartHandler so that it receives it from the parent for passing it on to the div. The same is true of the style and class bindings, which are also not working as you expect, but you don't see an error there because those are built-in bindings which get transferred to the root element.
Cube.vue
render() {
...
},
props: {
dragstartHandler: {
type: Function,
},
}

Required property on a field doesn't change dynamically

One of my fields should be either mandatory(required) or not depending on one boolean variable. No matter if it changes or not the field stays required. Not sure what's wrong with my expressionProperties templateOptions.required as this is what triggers that change.
This is part of my formly form
vm.showDeleteButton = false;
vm.fields = [
{
className: 'row',
fieldGroup: [
{
className: 'col-xs-6',
key: 'transferDate',
type: 'datepicker',
templateOptions: {
label: 'Deallocation Date',
type: 'text',
datepickerPopup: 'dd/MM/yyyy',
minDate: vm.model.minDate,
maxDate: vm.model.maxdate,
},
expressionProperties: {
'templateOptions.required': !vm.showDeleteButton
}
}
]
}
];
Also tried this
expressionProperties: {
'templateOptions.required': function() {
if(!vm.showDeleteButton) {
return true;
else {
return false;
}
}
}
I've read the formly expressions documentation but that doesn't help either.
HTML as requested
<formly-form model="vm.model" fields="vm.fields" options="vm.options" form="vm.form"></formly-form>
Kind of 'hacked' it to work.
Changed vm.showDeleteButton to vm.model.showDeleteButton and in my expressionProperties wrote this
expressionProperties: {
'templateOptions.required': '!model.showDeleteButton'
}

Why can't I see my neon-animeted tags, moving/fading-out/etc.?

The code is working properly, but somehow it does not show any animations.
I mean using fade-out-animation, it only disappears, no matter what is the duration.
I've imported all the stuff I needed (fade-out-animation,polymer,webcomponents,neon-animation-runner-behavior)
Polymer({
is: 'test-animation',
behaviors: [Polymer.NeonAnimationRunnerBehavior,Polymer.NeonAnimationBehavior],
properties: {
opened: {
type: Boolean
},
animationConfig: {
value: function() {
return {
'entry': {
name: 'slide-from-right-animation',
node: this,
timing: {delay: 2000, duration: 6000}
},
'exit': {
name: 'fade-out-animation',
node: this,
}
}
}
}
},
listeners: {
'neon-animation-finish': '_onNeonAnimationFinish'
},
show: function() {
this.opened = true;
//this.cancelAnimation();
this.playAnimation('entry');
},
hide: function() {
this.opened = false;
// this.cancelAnimation();
this.playAnimation('exit');
},
_onNeonAnimationFinish: function() {
if (!this.opened) {
this.style.display = 'none';
}
}
});
I think you made a mistake in the imported behaviors.
You are using :
-Polymer.NeonAnimationRunnerBehavior, which is correct since your component is running an animation.
-Polymer.NeonAnimationBehavior, which is incorrect: this behavior is meant for creating an animation (fade, slide, whatever you wish). You, on the other hand, want your component to be animatable (meaning, having a Polymer.NeonAnimationBehavior applied to it). The correct behavior for that is Polymer.NeonAnimatableBehavior
So you should change:
behaviors: [Polymer.NeonAnimationRunnerBehavior,Polymer.NeonAnimationBehavior]
to :
behaviors: [Polymer.NeonAnimationRunnerBehavior,Polymer.NeonAnimatableBehavior]
Edit :
I can confirm this was indeed the problem, as I tested this solution successfully.
However, you also have some coma and semi-colon problems in the declaration of your animation. It should be as follows :
animationConfig: {
value: function() {
return {
'entry': {
name: 'slide-from-right-animation',
node: this,
timing: {
delay: 2000, duration: 6000
}
},
'exit': {
name: 'fade-out-animation',
node: this
}
};
}
}

Set value in Backbone.Form after fetch from the server

Hi I am newbie in Backbone and JS.
I need to fetch data from the server and put this value as the default to planProviderMode choice radio button. So i fetch the data in defaultMode variable. But the call is a asynchronous and I receive a value after the planProviderMode: defaultMode.value code has been executed.
var PlanProviderMode = Backbone.Model.extend({
url: '/rest/enrollment/step/plan-provider-mode'
});
var defaultMode = new PlanProviderMode;
defaultMode.fetch({
success: function() {
// recieve correct data
}
});
var formItems = new Backbone.Form({
template: tpl,
className: 'wizard-content',
schema: {
planProviderMode: {
template: formTpl,
type: 'Radio',
options: [
{
label: 'By Plan',
val: 'BY_PLAN',
custom: {
img: '../resources/img/by-plan.jpg'
}
},
{
label: 'By Provider',
val: 'BY_PROVIDER',
custom: {
img: '../resources/img/by-provider.jpg'
}
}
]
}
},
//here i put the default value
data: {
planProviderMode: defaultMode.value
}
});
How could I set the fetched value to the form.
Please let me know if the question is not described well. Thanks.
you should write such code in success callback function which is executed only after the fetch request is completed succesfully.
var PlanProviderMode = Backbone.Model.extend({
url: '/rest/enrollment/step/plan-provider-mode'
});
var defaultMode = new PlanProviderMode;
defaultMode.fetch({
success: function() {
// recieve correct data
//here you put the default value
data: {
planProviderMode: defaultMode.value
}
}
});
var formItems = new Backbone.Form({
template: tpl,
className: 'wizard-content',
schema: {
planProviderMode: {
template: formTpl,
type: 'Radio',
options: [
{
label: 'By Plan',
val: 'BY_PLAN',
custom: {
img: '../resources/img/by-plan.jpg'
}
},
{
label: 'By Provider',
val: 'BY_PROVIDER',
custom: {
img: '../resources/img/by-provider.jpg'
}
}
]
}
}
});
Backnone has a function called "parse" that helps you in this cases.
This function will always be called from backbone before the data from server populate the model.
Take a read in parse method.
There's a answer here.
how to override Backbone's parse function?
Hope it helps

How to add function on table fields - Backbone.js

I have this code in a Backbone application that I need to debug. (rough idea)
window.TableView = Backbone.View.extend({
initialize: function() {...
..
..
...
});
},
selectRow: function() {
...
...
..
},
render: function() { // this renders my models fields in a table
var editableColumns = [
//{ name: "display", type: "combobox", combobox: comboboxOptions, validate: validateText },
{ name: "display" },
{ name: "submitDate", type: "datepicker", datepicker: datepickerOptions },
{ name: "displayDate", type: "datepicker", datepicker: datepickerOptions },
{ name: "name"},
...
...
Now my problem is, how can I add a function to this field: { name: "display" }
like onclick, or after focus function, etc.? For example can I have,
{ name: "display", onclick: setMyText(); } or something like this? Also is this part of backbone.js or one of its components? Where can I read more about this?
In Backbone you have events hash for a View where you can specify the events for respective View. Events are specified in following format:
{"event selector": "callback"}
So in your case for all the editableColumns you also need a selector for each one or may you can specify by using the name property. Try specifying the events hash like this :
events: {
'click .columnSelector[name="display"]' : "setMyText"
}
where .columnSelector is the class applied to element that is to be edited.
For more details on events check this.

Categories

Resources