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

feature(dirty-binding-behavior): Add the dirty binding behavior #333

Closed
wants to merge 2 commits into
base: master
from

Conversation

Projects
None yet
5 participants
@davismj
Member

davismj commented Nov 6, 2017

When binding arbitrary expressions that depend on complex objects there are no tools to either observe the dependencies or force a regular update. The dirty binding behavior adds a binding behavior that overrides the default binding and instead forces regular updates. The default update interval is 100ms, which research has shown is the threshold for an action to be perceived as instantaneous (see here: https://ux.stackexchange.com/questions/2/what-is-an-acceptable-response-time-for-my-ajax-ui/4#4). Developers can customize the responsiveness of the binding behavior by specifying a different update interval in ms as a parameter of the binding behavior.

Examples:

<div>100ms, or 10fps: ${obj | toJson & dirty}</div>
<div>16ms, or 60fps: ${obj | toJson & dirty: 16}</div>

davismj added some commits Nov 6, 2017

feature(dirty-binding-behavior): Add a dirty binding behavior that re…
…gularly checks for updates

When binding arbitrary expressions that depend on complex objects there are no tools to either observe the dependencies or force a regular update. The dirty binding behavior adds a binding behavior that overrides the default binding behavior and instead forces regular updates. The default update interval is 100ms, which research has shown is the threshold for an action to be perceived as instantaneous (see here: https://ux.stackexchange.com/questions/2/what-is-an-acceptable-response-time-for-my-ajax-ui/4#4). Developers can customize the responsiveness of the binding behavior by specifying a different update interval in ms as a parameter of the binding behavior.

Examples:

100ms, or 10fps: <div>${obj | toJson & dirty}</div>
16ms, or 60fps: <div>{${obj | toJson & dirty: 16}</div>
chore(aurelia-templating-resources): Add dirty binding behavior to ex…
…ports

Also, globalize the binding the behavior.
@davismj

This comment has been minimized.

Show comment
Hide comment
@davismj
Member

davismj commented Nov 6, 2017

@jdanyow

This comment has been minimized.

Show comment
Hide comment
@jdanyow

jdanyow Nov 13, 2017

Member

We do have this build-in!

get pointsFormatted() {
  return JSON.stringify(this.points);
}

Needing to use & dirty is a code smell I think we can avoid by moving method calls to the input/change event side instead of polling from the view/observation side.

Member

jdanyow commented Nov 13, 2017

We do have this build-in!

get pointsFormatted() {
  return JSON.stringify(this.points);
}

Needing to use & dirty is a code smell I think we can avoid by moving method calls to the input/change event side instead of polling from the view/observation side.

@jdanyow jdanyow closed this Nov 13, 2017

@davismj

This comment has been minimized.

Show comment
Hide comment
@davismj

davismj Nov 13, 2017

Member
Member

davismj commented Nov 13, 2017

@jdanyow

This comment has been minimized.

Show comment
Hide comment
@jdanyow

jdanyow Nov 13, 2017

Member

Can you put together a gist showing the problem with svgs?

Member

jdanyow commented Nov 13, 2017

Can you put together a gist showing the problem with svgs?

@bigopon

This comment has been minimized.

Show comment
Hide comment
@bigopon

bigopon Nov 13, 2017

Member

What also nice about this is the fine control of dirty checking frequency, as a third paramatar for the binding behavior. There is similar one in enhancement list that we want to have configurable dirty checking behavior at aurelia/binding#563. So If we are not to have this built in, maybe lets reconsider that ?

Member

bigopon commented Nov 13, 2017

What also nice about this is the fine control of dirty checking frequency, as a third paramatar for the binding behavior. There is similar one in enhancement list that we want to have configurable dirty checking behavior at aurelia/binding#563. So If we are not to have this built in, maybe lets reconsider that ?

@davismj

This comment has been minimized.

Show comment
Hide comment
@davismj

davismj Nov 13, 2017

Member

If we want to talk about smell, let's talk about the design of dirty checking today. The "best practice" is to tell Aurelia to dirty to check your function by dumping it in the only structure Aurelia doesn't know how to observe. That isn't design, that's a hack, and a stinky one.

  • It's imperative, not declarative
  • It gives you no control over the dirty checking behavior
  • It is not scalable: If you need 5 functions dirty checked, you have to write 5 separate getter functions; if you need n functions dirty checked, you have to write the binding behavior in this pull request.

A dirty checking binding behavior solves all of this

  • Allows specifying dirty checking behavior declaratively
  • Gives tight control over the behavior that can be tuned to specific requirements
  • Allows dirty checking arbitrary values, not just parameterless getter functions
  • DRYs code

It also solves a number of issues that people constantly complain about. The work itself was based off of Jason Sobell's solution to the following issue: aurelia/binding#147. As mentioned in the comments, binding signal approaches both add quite a bit of complexity and only works with function calls, not property assignment. While I agree that there might be a potential for abuse--a consumer doesn't know why their binding isn't updating and instead of figuring it out they just dirty check it--but that is no less true today with the current dirty checking behavior. This is strictly an upgrade on the current implementation.

If you haven't seen it, here is the article I was wrote that motivated this pull request. http://davismj.me/blog/aurelia-computed-from-patterns/

Member

davismj commented Nov 13, 2017

If we want to talk about smell, let's talk about the design of dirty checking today. The "best practice" is to tell Aurelia to dirty to check your function by dumping it in the only structure Aurelia doesn't know how to observe. That isn't design, that's a hack, and a stinky one.

  • It's imperative, not declarative
  • It gives you no control over the dirty checking behavior
  • It is not scalable: If you need 5 functions dirty checked, you have to write 5 separate getter functions; if you need n functions dirty checked, you have to write the binding behavior in this pull request.

A dirty checking binding behavior solves all of this

  • Allows specifying dirty checking behavior declaratively
  • Gives tight control over the behavior that can be tuned to specific requirements
  • Allows dirty checking arbitrary values, not just parameterless getter functions
  • DRYs code

It also solves a number of issues that people constantly complain about. The work itself was based off of Jason Sobell's solution to the following issue: aurelia/binding#147. As mentioned in the comments, binding signal approaches both add quite a bit of complexity and only works with function calls, not property assignment. While I agree that there might be a potential for abuse--a consumer doesn't know why their binding isn't updating and instead of figuring it out they just dirty check it--but that is no less true today with the current dirty checking behavior. This is strictly an upgrade on the current implementation.

If you haven't seen it, here is the article I was wrote that motivated this pull request. http://davismj.me/blog/aurelia-computed-from-patterns/

@davismj

This comment has been minimized.

Show comment
Hide comment
@davismj

davismj Nov 24, 2017

Member

@jdanyow We don't have this built in. This just came up again today while trying to write blog content on decorators in Aurelia.

https://gist.run/?id=3295297e1cbe1000088bc21ebe842c73

Member

davismj commented Nov 24, 2017

@jdanyow We don't have this built in. This just came up again today while trying to write blog content on decorators in Aurelia.

https://gist.run/?id=3295297e1cbe1000088bc21ebe842c73

@atsu85

This comment has been minimized.

Show comment
Hide comment
@atsu85

atsu85 Nov 24, 2017

@jdanyow, could You either reopen this PR or at least provide additional comments?

atsu85 commented Nov 24, 2017

@jdanyow, could You either reopen this PR or at least provide additional comments?

@jsobell

This comment has been minimized.

Show comment
Hide comment
@jsobell

jsobell Jan 22, 2018

@davismj I wonder if perhaps the issue is that the inability to detect changes in this way using Aurelia is "the elephant in the room". Property interceptors meet requirements for 90% of cases, but the other 10% can't all be fixed using signals (as is the usual suggestion). To raise a signal the client often needs to know if the contents has been changed, so ends up doing its own dirty checking.

I've pushed for over two years to have this adopted, and I posted three articles on ways of approaching it in my blog because it's been one of the most frequently asked question on the Aurelia Gitter chat room.

I think we should either re-open this or give a darned good reason why we don't want to adopt it as an option.

jsobell commented Jan 22, 2018

@davismj I wonder if perhaps the issue is that the inability to detect changes in this way using Aurelia is "the elephant in the room". Property interceptors meet requirements for 90% of cases, but the other 10% can't all be fixed using signals (as is the usual suggestion). To raise a signal the client often needs to know if the contents has been changed, so ends up doing its own dirty checking.

I've pushed for over two years to have this adopted, and I posted three articles on ways of approaching it in my blog because it's been one of the most frequently asked question on the Aurelia Gitter chat room.

I think we should either re-open this or give a darned good reason why we don't want to adopt it as an option.

@davismj

This comment has been minimized.

Show comment
Hide comment
@davismj

davismj Jan 30, 2018

Member

@jsobell @atsu85 I've added this as the refresh binding behavior to the aurelia-plus library. Take a look here for more info. I'd love to hear your feedback. http://aurelia.plus/

Member

davismj commented Jan 30, 2018

@jsobell @atsu85 I've added this as the refresh binding behavior to the aurelia-plus library. Take a look here for more info. I'd love to hear your feedback. http://aurelia.plus/

@jsobell

This comment has been minimized.

Show comment
Hide comment
@jsobell

jsobell Jan 30, 2018

@davismj Looks good! I'll have a look at it all with Binh tomorrow

jsobell commented Jan 30, 2018

@davismj Looks good! I'll have a look at it all with Binh tomorrow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment