-
Notifications
You must be signed in to change notification settings - Fork 62
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
How does the property directive work? #111
Comments
import 'slim-js/property-directive'
Edit: User error in my attempt to add some debugging statements. |
So two things I figured out:
Working example: import { Slim } from 'slim-js';
import 'slim-js/property-directive';
Slim.element(
'my-greeting',
/*html*/ `
<h1>Hello, {{this.who}}!</h1>
`,
class MyGreeting extends Slim {
constructor() {
super()
if (this.hasOwnProperty("who")) {
console.log(`inside constructor: ${this.who}`);
}
}
}
);
Slim.element(
'my-app',
/*html*/ `
<my-greeting .who="{{this.who}}"></my-greeting>
<my-greeting .who="{{this.another}}"></my-greeting>
`,
class MyApp extends Slim {
who = "I am the one and only"
another = "And I'm another one!"
}
); I know that pre-binding properties in javascript before the constructor is called is a common pattern in some frameworks, but it still feels a bit hackish to me. Maybe you could elaborate more on this? |
Hi. Are you using any babel/transpiling tools? These affect the way class properties are declared. Some tools use Object.defineProperty and thus destroy the internals. |
I use webpack 5 with |
Regarding your question. For example, an expression like When the class is constructed, there is a dedicated function that executed the expression as-is, bound to the class' instance. If your tool intervenes in the native class property declarations, it may destroy the mechanics. Either avoid transpiling class properties, or just initialize those in the constructor. |
The directives are optional, therefore can be consumed separately. The property simply executes the content of the expression every time a detected (and relevant) change occurs, and updates the property on the target element. In that case, when you change the parent's component
The parent class gets a |
Yes and this is a really nice feature I like. It's just how the initial value of the property is set as you say:
So initially, in the first load the constructor of the element is called after the properties are bound to the instance (with the property directive), so should I detect that in the constructor then? |
Before anything else: Thank you for answering this (and thanks for this awesome framework too!!) So, to rule out any webpack or transpiling, a pure browser version: <!DOCTYPE html>
<html>
<head>
<title>Properties with Slim.js</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<script type="module">
import { Slim } from 'https://unpkg.com/slim-js@5.0.10/dist/index.js';
import 'https://unpkg.com/slim-js@5.0.10/dist/directives/property.directive.js';
Slim.element(
'my-greeting',
`
<h1>Hello, {{this.who}}!</h1>
`,
class MyGreeting extends Slim {
constructor(who) {
super()
if (this.hasOwnProperty("who")) {
console.log(`who property already set: ${this.who}`);
}
}
}
);
Slim.element(
'my-app',
`
<my-greeting .who="{{this.who}}"></my-greeting>
<my-greeting .who="{{this.another}}"></my-greeting>
`,
class MyApp extends Slim {
who = "I am the one and only"
another = "And I'm another one!"
}
);
</script>
</head>
<body>
<my-app></my-app>
</body>
</html> When I define a class property called who: class MyGreeting extends Slim {
who = "my default value
...
} or when I initialize it in the constructor class MyGreeting extends Slim {
constructor() {
super()
this.who = "my default who"
...
}
} It will overwrite the initial who property defined with var app = document.querySelector("my-app")
app.who = "Updated who!" It will update the component as expected. So to get around the initial value of this if (!this.hasOwnProperty("who")) {
this.who = "My default who"
} I don't think this is how it is intended? |
It sounds like something needs to be fixed. I'll try your example as-is. |
Interestingly enough, the test in f5b5fbf is passing, so in the JSDOM browser, the constructor is called before the directive is handling the property. |
The constructor should always be called first. |
When I create a simplified example of the example on the Creating an Element documentation page:
I expect that
this.who
will be set with the.who
property, but whatever I do, it staysundefined
.I guess I don't understand the concept of the
.who
property, could you explain how this works?The text was updated successfully, but these errors were encountered: