aurelia / templating-binding

An implementation of the templating engine's Binding Language abstraction which uses a pluggable command syntax.
MIT License
32 stars 26 forks source link

binding behaviors #25

Closed jdanyow closed 9 years ago

jdanyow commented 9 years ago

Ability to associate a name with a binding or collection of bindings. Bindings will update when you “signal” them by name.

EisenbergEffect commented 9 years ago

Note that we need to implement our binding options syntax in order to handle this. I was thinking something like this: <span>${createdAt | timeAgo & signal:timerTick }</span> In the way that filters use | we could use &. I hadn't tested this in html content to ensure that we would get the right characters from the DOM though. Thoughts?

jdanyow commented 9 years ago

I was curious how that would be expressed- I like it.

Assuming https://github.com/aurelia/templating-binding/issues/24 would work similarly? <span>${firstName & one-time}</span> ?

EisenbergEffect commented 9 years ago

Yep. That's the idea at least.

jdanyow commented 9 years ago

Need to consider https://github.com/aurelia/binding/issues/61 when implementing this.

jdanyow commented 9 years ago

I was thinking these three related enhancements: signals, throttling and the ability to express one-time interpolation bindings could be built on a common feature: BindingBehaviors.

A BindingBehavior will have the ability to add custom logic to a binding's lifecycle.

Developers will be able to supply custom BindingBehaviors, similar to the ValueConverter functionality.

Aurelia will supply several BindingBehaviors out of the box, namely for the three enhancements listed above.

Thoughts?

EisenbergEffect commented 9 years ago

Yes. Yes. Yes. Those are my three thoughts :)

jdanyow commented 9 years ago

@EisenbergEffect initial work for binding behaviors support:

(ignore the 3798cb1 commit above from 5 days ago)

If you have a chance to review this before I get to far along it would be appreciated!

EisenbergEffect commented 9 years ago

Wow. I did not expect this so soon. I'd love to take a look. Anything in particular you aren't sure about? or feel pretty good about it?

EisenbergEffect commented 9 years ago

Ok, you've got everything connected in right, as far as I can tell at first glance. So, the real trick is getting the actual AST node implemented. I hadn't originally thought of this as an extensibility point...but I like that you went that way. If we can make that work...that will be even cooler than what I had in mind :)

jdanyow commented 9 years ago

nice! I'll keep plugging away then...

jdanyow commented 9 years ago

@EisenbergEffect ^^^

that's working code, still pretty rough- doesn't handle multiple binding behaviors in the same binding expression yet- let me know if you have any ideas to improve/optimize this.

Example expressions:

${firstName & debounce:200}
${fullName | upper & throttle:500}
${fullName | upper & oneTime}
EisenbergEffect commented 9 years ago

I think we should probably put this aside until after we do the re-work on the binding engine.

fopsdev commented 9 years ago

now wouldn't it be awesome if we could decorate the properties on the viewmodel with something like @signal = tick and then those guys in the view get updated on that signalevent? then we wouldn't need to clutter the view with this additional binding information... just as an idea... maybe even go one step further and use decorators for throttling and the other behaviours as well.

EisenbergEffect commented 9 years ago

@jdanyow Making a note here. When we do this, we also need the ability to change the event that is used for two-way binding. So, for example if someone wants inputs to bind to models on blur instead of change.

sylvain-hamel commented 9 years ago

Hi, just some feedback from an newcomer here: I feel like making the interpolation syntax more complex to support these special cases is not ideal. I've seen other frameworks use special symbols and it makes the code hard to understand for newcomers.

Here is a suggestion:

Keep the interpolation syntax the same:

<span>${special}</span>

And let the VM define the attribute as an instance of a framework type (InterpolationExpression for instance):

export class VM {
 constructor(){

  this.myfield = 10283;

  this.special = new InterpolationExpression({
    expression : "myfield",
    throttle : 200,
    oneTime : true
  });

 }
}

This would also let you or others extend the InterpolationExpression class to add new features.

Hope this helps

EisenbergEffect commented 9 years ago

The behaviors concept is extensible just the same way that filters are. You simply create a class and you add new behavior.

sylvain-hamel commented 9 years ago

I understand that. I'm just afraid that this might lead to a complex syntax if behaviors eventually need complex parameters. So I'd rather specify the behaviors in code then in the markup. Maybe it's just a matter of preference.

tlvenn commented 9 years ago

Hi @jdanyow , any update on this front ?

jdanyow commented 9 years ago

hey @Tlvenn - here's the status- (@EisenbergEffect, please correct me if I'm wrong on this)

The benchmarking infrastructure is in place and the binding module optimization work is about to start. You can expect to see this feature in Aurelia within 6 weeks, hopefully less.

jdanyow commented 9 years ago

By the way, if you need async binding, here's an experimental plugin: aurelia-async

I haven't blogged/announced this but it's there if you want to play around with it or fork it to support your use case.

tlvenn commented 9 years ago

Thanks for the update and the pointer Jeremy.

heruan commented 9 years ago

Would this permit also to update an observed property bound to an <input type="text"> only when input.validity.valid == true? I have forms with strict HTML5 validity constraints and I'd prefer the bound properties not to update while the input value isn't valid.

jdanyow commented 9 years ago

We're working on this right now- will have more info for you in a day or two. I think you'll have full access to the binding instance so you'll be able to do just about anything, including putting additional guards between the view and the model.

jdanyow commented 9 years ago

support for this in next release https://github.com/aurelia/binding/pull/196