LitElement rendering template without values - javascript

I've got a simple example demonstrating what I'm seeing: https://stackblitz.com/edit/lit-element-example-3pdnwk?file=index.js.
Basically when the first child element renders, the text property is set correctly. However on the second render, the text property is undefined first and then updated to be the correct value.
This breaks being able to depend on _firstRendered() to have the correct values assigned to the properties.
Am I doing something really off here?
Update: Here is a better example using a similar method provided in the lit-html documentation: https://stackblitz.com/edit/lit-element-issue?file=index.js

Am I doing something really off here?
maybe? :) Hopefully you can help me to understand why you chose your implementation and I can look into it further.
The part I'm stuck on is why you create and replace the child element inside the parent element like this:
this._child = html`<child-element text="${text1}"></child-element>`;
From what I understand so far, that code uses a lit-html helper function to create a lit-html TemplateResult. You then replace it with another one in the timeout callback:
this._child = html`<child-element text="${text2}"></child-element>`;
So instead of just re-drawing only the stuff that changed (a string), your code creates a new TemplateResult and redraws that. This also calls the child element constructor again and causes the text node to go undefined for a moment as you noted. Here is console output added to your impl to show when the constructor and render functions get called for parent and child:
https://stackblitz.com/edit/lit-element-example-ftlbz7?file=index.js
From inspecting the DOM tree, your example produces this DOM structure:
<parent-element>
#shadow-root
<div>
<child-element>
#shadow-root
<div>
Suppose I need to produce that same DOM structure and have the same text node update in response to the timeout callback, I would probably handle it in the parent render function:
_render({ parenttext }) {
return html`<div><child-element text="${parenttext}"></child-element></div>`;
}
which ensures that the child constructor is only called once, and only the data that actually changes gets redrawn.
If I understand correctly, that's how lit-element is designed to be used (expressing an app or element's render as a function of its data). That way we can rely on the browser to just redraw any changes to the data. This should theoretically be faster (altho I haven't tested it).
Code sample here:
https://stackblitz.com/edit/lit-element-example-exrlxw?file=parent-element.js
Lmk what I'm missing from your tests and I can look into it more.
Edited to add:
I noticed that overriding _shouldRender to prevent the element from rendering with undefined props prevented the element from rendering with undefined props, but it didn't fix _firstRendered, which was still firing when props were undefined.
_firstRendered, unlike _didRender, is not specifically called as a result of _render; it is called from the ready() callback, which is inherited from Polymer's properties-changed mixin. In Polymer, ready() fires when the element is added to the DOM. I thought properties should be initialized by then, so this is still pretty weird.
Anyways, this means it is possible to create an element that never renders (i.e _shouldRender always returns false), but _firstRendered still fires. Lol. Sample: https://stackblitz.com/edit/lit-element-first-rendered?file=index.js.
I'm not honestly sure what to make of any of this. I'll raise an issue on the lit-element github when I've read a few more things from the documentation (or you can, if you get there first).

This is no longer an issue as of 0.6.0-dev.5

Related

Hoe to removeAll on Ext.query('.classname')-EXTJS

I want to remove all the elements from the array using:
Ext.query('.classname') // gets me array of elements
the Ext.query('.classname').removeall() is not a function it supports, how to achieve this?
thanks
guess it should be something alike this:
Ext.ComponentQuery.query('panel[cls=classname]').each(function(cmp) {
cmp.destroy();
});
Ext.query is actually Ext.dom.query, therefore it will not return the component
... alike Ext.ComponentQuery does.
explanation: the question does not indicate against what the code shall run; therefore I'd assume it to be ExtJS components - and not the HTML content within a ExtJS panel (which would have no representation within the framework). the point is, that when removing DOM nodes, without destroying the associated components, this will leave orphaned references behind. therefore destroying them properly is suggested, so that those won't needlessly occupy RAM anymore, eg. in case removing DOM nodes and then adding new ExtJS components, over and over again - this would lead to sluggish behavior.
Use Ext.select, which wraps the return elements so that you can call Ext.dom.Element methods as though they were a group:
Ext.select('.even').remove();
Fiddle.

Polymer Custom Element Shadow DOM issues

I am attempting to use the Polymer shadow DOM " $ " object.
document.querySelector("recent-activity-section").$
This code should return an object that looks like this:
Object {recent-activity-section: section#recent-activity-section, recent-activity-div: div#recent-activity-div, list: core-list#list}
In fact, using the Chrome Dev Tools console, it does.
However, inside of the "created" function in the javascript file that goes along with my custom element, I get the following:
undefined
Perhaps I'm using something wrong?
Instead of using the created method, which is one of the first ones triggered in the element's lifecycle, you would probably have more luck using domReady, which is, according to Polymer official docs:
Called when the element’s initial set of children are guaranteed to exist. This is an appropriate time to poke at the element’s parent or light DOM children.

Howto: generic test to see if widgets call this.inherited succesfully?

I maintain a custom library consisting of many dijit widgets at the company I work at.
Many of the defects/bugs I have had to deal with were the result of this.inherited(arguments) calls missing from overriden methods such as destroy startup and postCreate.
Some of these go unnoticed easily and are not always discovered until much later.
I suspect I can use dojo\aspect.after to hook onto the 'base' implementation, but I am not sure how to acquire a handle to the _widgetBase method itself.
Merely using .after on the method of my own widget would be pointless, since that wouldn't check whether this.inherited(..) was inded called.
How can I write a generic test function that can be passed any dijit/_WidgetBase instance and checks whether the _widgetBase's methods mentioned above are called from the widget when the same method is called on the subclassing widget itself?
Bottom-line is how do I acquire a reference to the base-implementation of the functions mentioned above?
After reading through dojo's documentation, declare.js code, debugging, googling, debugging and hacking I end up with this piece of code to acquire a handle to a base method of the last inherited class/mix-in, but I am not entirely happy with the hackiness involved in calling getInherited:
Edit 2 I substituted the second param of getInherited with an empty array. While I actually get a reference to the method of the baseclass using aspect doesn't work. It appears this approach is a bust.
require(['dijit/registry','dojo/_base/declare','mycompany/widgets/widgetToTest'],
function(registry,declare,widgetToTest)
{
var widget = registry.byId('widgetToTestId');
var baseStartup = getBaseMethod(widget,'startup');
function getBaseMethod(widget,methodName){
return widget.getInherited(methodName,[]);
}
//This is the method body I want to use .after on to see if it was called, it returns the last overriden class in the array of inherited classes. (a mixin in this case, good enough for me!)
alert(baseStartup);
});
I have given up trying to use dojo/aspect.
I have instead opted to modify the code of our custom base widget to incorporate snippets such as the one below. They are automatically removed when creating a release-build in which console-calls and their content are removed:
console.log(
function(){
(this._debugInfo = this._debugInfo|| {}).postCreate=true;
}.call(this)
);
A simple method in boilerplate code I added near the unittests is available so that I can call it on all mycompany.widgets.basewidget instances in their respective unittests.

React component with dynamically created function

I have a React component that includes an input element. When the value of the input changes the handler function is supposed to validate the input and act accordingly. The actual validator is dynamically created (via new Function(code)) with the actual code passed as a string prop to the element. The validation code never changes for a given component.
Right now I am doing the function construction in the actual onChange handler which seems unnecessary. It does not belong in state either. I would like to create the function once, store it somewhere and use it on demand. My question is, where should it be stored? Should I make it an attribute of the actual component object? The statics object seems also reasonable, but can one pass properties dynamically (like the code string above) and if yes, how?
Recomputing the validator inside the onchange is not that bad from a reproducibility point of view. It only affects performance and if that is an issue one possibility would be to use the caching mechanism of your choice:
handleOnChange: function(){
if(this.cachedValidatorString !== this.props.validatorString){
this.cachedValidatorString = this.props.validatorString;
this.cachedValidator = new Function(...);
}
// ...
}
Another, perhaps cleaner, approach would be to update the validatorFunction field inside the render method. That is the earliest you can update it and it guarantees that it will always correspond to your current props.
render: function(){
this.validatorFunction = new Function(this.props.validatorString);
return <input onChange={...} />;
}
As for the other possibilities you mentioned:
I agree that this.state is not the best place to put the validator function because in general you want to avoid putting things that can be computed from the props in the state. See props in getInitialState as an anti pattern
Finally, I don't think statics would make much sense here. Static properties are shared by all instances of your class but the validator functions need to be different for each instance of the component.

Subscribing to changes in siblings with Knockout.js

I'm using inheritance to implmenet a reuseable forms app.
Expression parameter can be dependent on one or more other numeric/constant ot other expression parameters (the relation is many to many so heirarchy wont work here). Once all my dependent parameters evaluated them self (calcualted if expression or validated if user input) I can now calculate my self.
I'm looking for a way to subscribe to my siblings but the problem is that during creation the sibling does not neccasarily exists yet.
I set up a small example on this Fiddle.
To see this not working in action lets change the values from the console
d.parameters()[0].value(10) // expecting parameter C to sum up to 20.
d.parameters()[2].value() // Nothing (this should also update ont he screen).
d.parameters()[1].value(20) // expecting parameter C to sum up to 30.
d.parameters()[2].value() // Still nothing.
So Ive tried sevral things but i think i'm barking up the wrong tree here.
Fetching the parent using ko.dataFor(document.body) or
fetching the object from the DOM using the same function.
I've played around with deferEvaluation as you can see in the code
to force KO to first create the parameters and then apply the
binding. seems to do nothing.
Tried creating a observableArray with the links to the params and a
computed based on the array but the problom remain.
Appreciate any help here.
Bonus question, without losing focus from the main one, somehing I cant explain going on on line 73.

Categories