Skip to content
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

Make class properties observable #104

Merged
merged 18 commits into from
Jun 11, 2020
Merged

Make class properties observable #104

merged 18 commits into from
Jun 11, 2020

Conversation

cherifGsoul
Copy link
Member

@cherifGsoul cherifGsoul commented Apr 6, 2020

This makes class properties observable:

class MyElement extends StacheElement {
		greetings = 'Hello';
                static get view() { return {{ greetings }}}
		static get props() {
		}
}
customElements.define('my-element', MyElement)

In case of:

class MyElement extends StacheElement {
		greetings = 'Hello';
                static get view() { return {{ greetings }}}
		static get props() {
                       return {
				greetings: {type: String, default: 'Bonjour'}
			};
		}
}
customElements.define('my-element', MyElement)

It set the value of props.greetings by the classe property value.

For canjs/can-observable-mixin#79

Copy link
Contributor

@phillipskevin phillipskevin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good start @cherifGsoul!

@@ -20,3 +20,61 @@ QUnit.test("basics", function(assert) {
el.age = "33";
assert.equal(el.age, 33, "updated age");
});

try {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all of the tests that require class fields should go in their own file. Then the main test file can do this feature detection and create a variable like supportsClassFields. The wrap the require statement for the tests like

if(supportsClassFields) {
  require(...);
}

QUnit.test('Class fields should be observable', (assert) => {
class DefineElement extends mixinDefine(Object) {
greetings = 'Hello'; // jshint ignore:line
static get props() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are props required?

const el = new DefineElement();

if (el.hasOwnProperty('greetings')) {
el.initialize();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should probably check that the default value is correct.

el.initialize();

el.on('greetings', () => {
assert.ok('The class field is observable');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also check that the value and old value are correct?

}

const el = new DefineElement();
el.initialize();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You also need to check the value of greetings to make sure the precedence is correct.

assert.ok('The class field is observable');
});

el.greetings = 'Hola';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After this you should also check that setting the value to a non-string causes an error.

assert.ok('The class field is observable');
});

el.greetings = 'Hola';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also check that setting the value to a non-string works since expando properties like this are not typed.

src/mixin-props.js Show resolved Hide resolved
Copy link
Contributor

@phillipskevin phillipskevin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some comments on the docs.

Will review the code separately.

@@ -206,6 +206,31 @@ document.body.querySelector("button#remove").addEventListener("click", () => {
@codepen
@highlight 14-23,only


#### Observable class fields
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move this under the Defining an element's properties heading?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!


#### Observable class fields

`StachElement` class fields are observables like [can-stache-element/static.props static props],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

</script>
```
@codepen
@highlight 11,only
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The highlighting is off here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed!

<button on:click="this.increment()">+1</button>
`;

count: 6
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be count = 6;.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

count: 6
}
customElements.define("count-er", Counter);
</script>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also add a note in that you must either add the element to the page or call initialize in order for the prop value to be observable?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@cherifGsoul
Copy link
Member Author

@phillipskevin I updated the docs!

Copy link
Contributor

@phillipskevin phillipskevin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a couple small comments.

@codepen
@highlight 11,only

In order to make `count` property observable, either `count-er` element must be added to the page
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you put this in a blockquote? > and add Note: to the beginning?

@@ -135,6 +135,33 @@ customElements.define("count-er", Counter);
@codepen
@highlight 9-11,only

#### Observable class fields

`StachElement` [class fields](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Class_fields) like [can-stache-element/static.props static props],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is missing some words.

class fields are observable like...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I would just leave off the like static props piece. Just

StacheElement class fields are also observable.

...along with the example should be fine for now.

Copy link
Contributor

@phillipskevin phillipskevin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found one more issue.

test/test.js Outdated
if (supportsClassFields) {
//It doesn't work with require
//Even when change the above imports to require
steal.import('~/src/mixin-props-class-fields-test');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just tried this out in the canjs/canjs suite and this file can't be loaded since the ~ is the canjs folder. We'll need to figure out how to do this.

Copy link
Contributor

@phillipskevin phillipskevin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like you added steal-conditional and created the supports-class-fields module, but it is not being used to import the class field test file.

Also, there are still a couple issues with the docs that need to be cleaned up.

@cherifGsoul
Copy link
Member Author

It looks like you added steal-conditional and created the supports-class-fields module, but it is not being used to import the class field test file.

Also, there are still a couple issues with the docs that need to be cleaned up.

@phillipskevin I updated the docs
The test file was not in the commit, I added it.

Copy link
Contributor

@phillipskevin phillipskevin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple more small things.

@@ -135,6 +135,33 @@ customElements.define("count-er", Counter);
@codepen
@highlight 9-11,only

#### Observable class fields

`StachElement` class fields are also observable.,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add the link to class fields docs on MDN?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test/test.js Outdated
@@ -1,3 +1,14 @@
let supportsClassFields;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be removed now, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@phillipskevin phillipskevin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

@cherifGsoul cherifGsoul merged commit 4595991 into master Jun 11, 2020
@cherifGsoul cherifGsoul deleted the class-fields-props branch June 11, 2020 18:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants