Support: IE9+
Property observers, not object observers.
- works with any object, array, array-alike object, date.
- listen only for a specific single property change, array or date mutation.
- support deep nestings, like:
obj_addObserver(obj, 'foo.baz.qux.name', cb)
. - support breadcrumbs for nested objects.
obj.foo = { baz: { qux: { name: 'New name' } } }
would rebind listener and will trigger the 'name' listener callback. - after the component is removed all the listeners are also removed to prevent memory leaks.
-
Inline Binding Util
~[bind:EXPRESSION]
"Users name is ~[bind: name +'!']"
Can be used in literals and attribute values. Usually you would use this util for binding view with a model, but sometimes you may also need some special bindings. For that cases you can use ":bind" tag and define some custom binding provider for [setting/getting] [to/from] [DOM/Model]
-
Binded Statements
-
+if
+if (expression) {}
-
+for..of
+for (value of ARRAY) {} +for ((value, index) of ARRAY) {}
-
+for..in
+for (key in object) {} +for ((key, value) in object) {}
-
+each
+each (expression) {}
-
+with
+with (expression) {}
-
+visible
+visible (expression) {}
-
-
Custom Tag: fox complex binders, e.g. with setters/getters support for the component.
:bind ...;
:datepicker > :bind value='date' getter='getDate' setter='setDate';
Attributes
value
- model's propertyexpression
- evaluate and bind to the expression use insteadvalue
attributegetter / setter
- binding can be applied also for componentsbindingProvider
- {optional} - property name of a custom Binding Providerattr
- {optional} - attribute name of an elementprop
- {optional} - property name of an element-
- {default} - binds to parents .innerHTML
Component should trigger the
change
event to notify the binder.
- Custom Tag Handler:
:dualbind ...;
Binds Model to the parent node.
input type=text >
:dualbind value='currentUser.name';
Attributes
value
- property in a model to bindexpression
- parse and evaluate expression, listen to all variable changes in expression, (though it could be used instead "value" argument in single binder, but in dual binder "value" should be specified, if expression contains more then one variable reference)property
- {default: "element.value"} - property PATH in a PROVIDER to BINDchangeEvent
- {default: change} - event to listen for DOM Changesgetter
- {optional} - if parent is custom tag(controller) with getter you define some function to resolve valuesetter
- {optional} - if parent is custom tag(controller) with setter you define some function to apply valuebindingProvider
- {optional} - you can register custom binding provider with: mask.registerBinding(name, handler)
Support HTML elements:
textarea
input
withtext
,date
,time
,number
,email
etc.select
Usually you want to validate user inputs before setting them to the model and this custom tag is used in dualbind control to keep the model valid.
div > input type=text > :dualbind value='currentUser.name' {
:validate validatorName='validatorProperties' message='some message on invalid';
:validate maxLength=20 message='Max Length is 20 Characters'
}
Attributes
-
validatorName
- any register validator name Already defined validators:- match='some regexp'
- unmatch='some regexp'
- minLength='min str length'
- maxLength='maxLength'
- check='EXPRESSION' - argument name is "x" - example: :validate check="x>10" message="..";
// custom validation
mask.registerValidator('mycustom', {
validate: function(node, string){
return doSomeChecks(string);
// or if some check option specified ->
return doSomeChecks(node.attr.mycustom, string);
}
})
input type=text >
:dualbind value='user.username' {
// predefined validator
:validate minLength=3 message='Too Short';
// regexp validator
:validate match='^\w+$' message='Only chars and numbers';
// custom validator
:validate mycustom message='Foo Message';
// with check option `some_option`
:validate mycustom='some_option' message='Baz Message';
}
// Default Binding Provider Properties
this.ctr // :dualbind component
this.model // model object
this.element // HTMLElement
this.value // property PATH in a MODEL to BIND
this.expression // @default = this.value | expression to parse and evaluate
this.property // property PATH in a PROVIDER to BIND @default 'element.value' for dualbinder, OR 'element.innerHTML' for singlebinder
this.setter = node.attr.setter; // @default null, use controller function as setter
this.getter = node.attr.getter; // @default null, use controller function as getter
mask.registerBinding('bindingName', {
/**
* (Optional) override default Setter/Getter to/from a DOM
\*/
domWay: {
get: function(provider){
// get value from dom or the parent component
return value;
},
/**
* - provider(BindingProvider)
* - value (Object): new value, that should be set to the DOM
\*/
set: function(provider, value){
// set value to dom or the parent component
}
},
/**
* (Optional) override default Setter/Getter to/from an Object.
\*/
objectWay: {
/**
* - property (String): Dot chained, example: "user.name"
\*/
get: function(obj, property){
// get and return value
},
set: function(obj, property, value){
// set value to obj
}
}
})
©️ MIT — 2014-2015 — Atma Project