VoliJS / NestedTypes

BackboneJS compatibility layer for Type-R data framework.
https://volicon.github.io/Type-R/
MIT License
94 stars 17 forks source link

Add attribute-level validators #88

Closed gaperton closed 8 years ago

gaperton commented 9 years ago

ReactJS views are on the way, and we need to add some features to be used in data binding.

Currently, Date attributes may be assigned with invadid date, and numbers can become NaNs. Validators should prevent attribute assignment in case it will result in invalid value (which will effectively suppress invalid user input in React view).

First, we need a simple way to suppress these assignments. Something like .has.guard()

Custom guard conditions can be currently added using has.set. We might want to create explicit shortcut for that case, something like .has.guard( function( x ){ return true; })

For String types, .has.guard may take regexp as am argument.

For Number types, .has.guard may take array with a range. like Number.has.guard([ 0, 5 ]), or Number.has.guard([ 0, Infinity ]);

Consider usage of specific keywords for guards, like Number.has.range( 0, 1 ), or String.has.pattern(/Hello.*/)

With NestedTypes 1.0 core, adding these things are really easy.

There are different related problems here. 1) Sometimes we need to distinguish input rejection and attribute validation. For example, regexp for email cannot be used for input rejection. In this case, it might be useful to have inputs with local state, indicating the situation that value cannot be saved to the attribute. So, when state is not equal to the model, input will add some class like 'invalid'. In this case, we can put validators to the model, while input rejection must be defined either implicitly through attribute type or explicitly as prop. (!) Good approach (!) 2) Silent model attribute update rejection might lead to weird bugs. Might be dangerous feature.

Ok, so we will proceed with approach outlined in (1). Gonna be tricky, but it's right approach. May be we will need to use Nested.React as a base to make it a bit less tricky.

<Input model={ this.model } attr='email' />
gaperton commented 8 years ago

Implemented in 1.3 rc. Completely defferent proposal, btw, even cooler.