-
Notifications
You must be signed in to change notification settings - Fork 955
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inconsistencies with "previousValue" property on parts #198
Comments
So I just noticed the privateness of the The bad thing: The typescript compiler will still prevent you from using this property on the |
Thanks for the issue @mraerino, Indeed, the usage of My thinking up to now was that I'm implicitly assuming here that if another value type is passed to a part, that the code path that handles that type will overwrite At the very least this needs to be documented better, so 👍 |
So. I finally got time to put my head into this again. It seems like My directive (simplified)
So basically my use case is to apply DRY by delegating the application of common attributes and handlers to a directive. Problem: No performance optimization for the templateWhen I'm not able to keep track of the latter parameters I will not be able to figure out when to re-render the template, so I must do it every time. Meh. When looking into the directive api I was pretty happy there already was some kind of concept to help with dirty checking: The In the end, for the reasons outlined above, I did not use the property of the part, but extended the part object with my own property: export interface DirtyCheckingPart extends NodePart {
previousValue: any;
}
export const decorateInput = (
literal: TemplateResult,
name: string
): DirectiveFn => directive((part: DirtyCheckingPart) => {
const previous = part.previousValue || {};
const instance: TemplateInstance = previous.template !== literal.template
? new TemplateInstance(literal.template, part.instance._partCallback)
: previous.instance;
let element: HTMLElement = previous.element;
if(previous.instance !== instance) {
const fragment: DocumentFragment = instance._clone();
element = fragment.childNodes[0]
}
instance.update(literal.values);
if(previous.element !== element || previous.name !== name) {
// custom logic messing with the element
}
part.previousValue = {
instance,
element,
name,
template: literal.template
};
part.setValue(element);
return element;
}); I'm setting the value as well as returning it because of recent changes in the Directive API - this way will work with every version. ProposalThe part passed to the Directive API should expose a method/property to get the previous state of the part. By default this state should be set by the |
This was mostly fixed in #400 (and some other PRs) which standardized on a public
|
When recently implementing a directive I ran into issues with the
previousValue
property on thePart
interface.Expected behaviour
The Readme says it should be usable like this:
Which implies that the
previousValue
property will take the value set throughsetValue
on every class implementing thePart
interface.Actual behaviour
Only a subset of Parts actually track their previous value, but they only do in a private property. So actually the property is not available on the
Part
interface.Proposed solutions
previousValue
property mandatory on thePart
interface and implement it in every part type.Part
an abstract class instead of an interface and use it as a base class for the part types. It then could implement a defaultget previousValue()
accessor which returnsnull
.Obstacles
This would certainly have to be a breaking change since it would require changes on the user's classes which implement the
Part
interfaceHow could this property be useful to directive creators?
when()
directiveThe text was updated successfully, but these errors were encountered: