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

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

Closed
wants to merge 2 commits into from
Closed

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

wants to merge 2 commits into from

Conversation

davismj
Copy link
Member

@davismj 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>

…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>
…ports

Also, globalize the binding the behavior.
@davismj
Copy link
Member Author

davismj commented Nov 6, 2017

Working gist.run here: https://gist.run/?id=91c1f815f3df0ca78356a23facc769b2

@jdanyow
Copy link
Contributor

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
Copy link
Member Author

davismj commented Nov 13, 2017 via email

@jdanyow
Copy link
Contributor

jdanyow commented Nov 13, 2017

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

@bigopon
Copy link
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
Copy link
Member Author

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
Copy link
Member Author

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
Copy link

atsu85 commented Nov 24, 2017

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

@jsobell
Copy link

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
Copy link
Member Author

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
Copy link

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
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants