<commit_before># Managing Data in Enyo

## Overview

Working with data is a key part of building any application.  In a typical application, you may need to load records and lists of records from a back-end service, display that data in your application's views, accept input from users that change or create new data, keep views in sync with the changing data, and then persist the data back to a back-end location.  Enyo provides many features to make developing rich, data-driven applications as easy as possible using a minimal amount of code.  

At the center of Enyo's data layer is the concept of data observation and binding-- the ability to observe changes to properties of an object and have those changes automatically synced to properties of related objects.  This is most useful in binding view properties to your back-end data, but bindings in Enyo are very flexible and can be used between any two Enyo objects.

All Enyo Objects and Components support binding by default when values are changed through the `enyo.Object` `set()` function.  However, to make changes to properties of plain old JavaScript objects observable (for eample, JSON objects loaded from a back-end service), Enyo also provides `enyo.Model`, which is an object that wraps a plain JavaScript object and adds observation support, allowing your back-end data to be easily bound to Enyo objects and controls.  Further, Enyo provides `enyo.Collection` to wrap arrays of models, allowing observation of additions and removals to/from the collection.

Using these features, `enyo.Object`'s and `enyo.Model` properties can be bound to any view properties (and automatically kept in sync when the model changes).  Further, "collection-aware" view kinds such as `enyo.DataRepeater`, `enyo.DataList` and `enyo.DataGridList` that generated repeated controls based on a list of data can be bound to `enyo.Collection`s (and automatically re-rendered when the models in the collections change).

Last, Enyo provides API's on `enyo.Model` and `enyo.Collection` for easily fetching and persisting data to/from back-end sources such as HTTP-based Ajax and Jsonp endpoints.  These API's are also extensible to other sources for your data, such as data fetched via 3rd-party libraries or SDK's by sub-classing and registering new `enyo.Source` objects.

## Observers and Bindings

`enyo.Component` provides both declarative and programmatic API's for observing property changes and binding between properties of objects in the scope of the component.

### Observers

In Enyo, an observer is simply a function that is called when the value of the property being observed changes.  As a convention, Enyo automatically provides published property change observers in the form of `<property>Changed()` functions.  For example:

```
enyo.kind({
	name: "MyControl",
	published: {
		foo: ""
	},
	fooChanged: function(inOld) {	// Called when foo changes
		// Do something with "this.foo"
	}
});
```

In the above example, `fooChanged()` will be called when the `foo` setter is called:

```
	tapHandler: function() {
		this.set("foo", "bar");	  // Causes fooChanged() to be called
	}
```

You can declare your own observers that watch one or more properties by adding entries to the `observers` block of your kind:

```
enyo.kind({
	name: "MyControl",
	published: {
		publicProperty: 10
	},
	_protectedProperty: 42,
	observers: {
		watchValues: ["publicProperty", "_protectedProperty"]
	},
	watchValues: function(previous, current, property) {  // Called when either property changes
		// Do something with "this.publicProperty" and "this._protectedProperty"
	}
});
```
Note, as long as the property is chagned via the `set()` setter function of `enyo.Object`, any property (published or otherwise) is observable.  Also note that the long-form setters generated for published properties (e.g. `setPublicProperty`, for the example above internally call the generic `set()` function as well).

For programmaticly adding observers after your kind is created, you may use the `addObserver` and `removeObserver` functions supplied on `enyo.Object` (via the `enyo.ObserverSupport` mixin).

### Bindings

Bindings in Enyo are built on top of the basic observation capability above, and are responsible for propogating property value changes between two points: the source and target of the binding.  When the source of a binding changes, the new value is set to the target property.

You can declare bindings between properties in the scope of a component by adding entries to the `bindings` block of your kind.  In the example below, the value of the slider will be automatically set to the content of the label as the user drags the slider.  

```
enyo.kind({
	name: "MyValueSlider",
	components: [
		{kind: "moon.Slider", name:"slider"},
		{kind: "enyo.Control", name:"label"}
	],
	bindings: [
		{from: ".$.slider.value", to: ".$.label.content"}
	]
});
```
Note, the source (`from`) and target (`to`) properties of the binding are specified as string paths.  By convention, when the path starts with a dot (`.`) as in the example above, the path is relative to `this`.  If the path starts with a caret (`^`), the path is relative to the global scope.

By default, bindings are one-way, from the source to the target.  However, bindings can be specified as "two-way" by setting the `oneWay` flag to `false`:

```
enyo.kind({
	name: "MyValueSlider",
	published: {
		sliderValue: 10	// Initial value of slider
	},
	components: [
		{kind: "moon.Slider", name:"slider"},
		{kind: "enyo.Control", name:"label"}
	],
	bindings: [
		{from: ".sliderValue", to: ".$.slider.value", oneWay: false},	// two-way binding
		{from: ".$.slider.value", to: ".$.label.content"}				// one-way binding
	]
});
```

Note that with two-way bindings, the order of the `from` and `to` values still have meaning, since the initial value will be determined by the source (`from`) end.  In the example above, we are binding the `sliderValue` published property to the child slider's `value`, property.  The initial value of the slider will be determined by the published `sliderValue` property, but subsequent changes on the slider will be propagated back to the `sliderValue` published property.

An optional `transform` function may be provided on bindings to transform the value as it passes from the source to the target (or vice-versa, for two-way bindings):

```
enyo.kind({
	name: "MyValueSlider",
	components: [
		{kind: "moon.Slider", name:"slider", min: 0, max: 1},
		{kind: "enyo.Control", name:"label"}
	],
	bindings: [
		{from: ".$.slider.value", to: ".$.label.content", transform: function(val) {
			return "The slider value is " + Math.round(val * 100) + "%";
		}}
	]
});
```

If necessary, a bi-directional transform can be provided for two-way bindings by checking the second argument to the transform function to determine the direction the binding is firing: 

```
		{from: ".$.slider.value", to: ".$.input.value", oneWay:false, transform: function(val, dir) {
			if (this.dir == "source") {
				return (val * 100) + "%";<commit_msg>Update wording. DCO-1.1-Signed-Off-By: <NAME> <<EMAIL>><commit_after># Managing Data in Enyo

## Overview

Working with data is a key part of building any application.  In a typical application, you may need to load records and lists of records from a back-end service, display that data in your application's views, accept input from users that change or create new data, keep views in sync with the changing data, and then persist the data back to a back-end location.  Enyo provides many features to make developing rich, data-driven applications as easy as possible using a minimal amount of code.  

At the center of Enyo's data layer is the concept of data observation and binding-- the ability to observe changes to properties of an object and have those changes automatically synced to properties of related objects.  This is most useful in binding view properties to your back-end data, but bindings in Enyo are very flexible and can be used between any two Enyo objects.

All Enyo Objects and Components support binding by default when values are changed through the `enyo.Object` `set()` function.  However, to make changes to properties of plain old JavaScript objects observable (for eample, JSON objects loaded from a back-end service), Enyo also provides `enyo.Model`, which is an object that wraps a plain JavaScript object and adds observation support, allowing your back-end data to be easily bound to Enyo objects and controls.  Further, Enyo provides `enyo.Collection` to wrap arrays of models, allowing observation of additions and removals to/from the collection.

Using these features, `enyo.Object`'s and `enyo.Model` properties can be bound to any view properties (and automatically kept in sync when the model changes).  Further, "collection-aware" view kinds such as `enyo.DataRepeater`, `enyo.DataList` and `enyo.DataGridList` that generated repeated controls based on a list of data can be bound to `enyo.Collection`s (and automatically re-rendered when the models in the collections change).

Last, Enyo provides API's on `enyo.Model` and `enyo.Collection` for easily fetching and persisting data to/from back-end sources such as HTTP-based Ajax and Jsonp endpoints.  These API's are also extensible to other sources for your data, such as data fetched via 3rd-party libraries or SDK's by sub-classing and registering new `enyo.Source` objects.

## Observers and Bindings

`enyo.Component` provides both declarative and programmatic API's for observing property changes and binding between properties of objects in the scope of the component.

### Observers

In Enyo, an observer is simply a function that is called when the value of the property being observed changes.  As a convention, Enyo automatically provides published property change observers in the form of `<property>Changed()` functions.  For example:

```
enyo.kind({
	name: "MyControl",
	published: {
		foo: ""
	},
	fooChanged: function(inOld) {	// Called when foo changes
		// Do something with "this.foo"
	}
});
```

In the above example, `fooChanged()` will be called when the `foo` setter is called:

```
	tapHandler: function() {
		this.set("foo", "bar");	  // Causes fooChanged() to be called
	}
```

You can declare your own observers that watch one or more properties by adding entries to the `observers` block of your kind:

```
enyo.kind({
	name: "MyControl",
	published: {
		publicProperty: 10
	},
	_protectedProperty: 42,
	observers: {
		watchValues: ["publicProperty", "_protectedProperty"]
	},
	watchValues: function(previous, current, property) {  // Called when either property changes
		// Do something with "this.publicProperty" and "this._protectedProperty"
	}
});
```
Note, as long as the property is chagned via the `set()` setter function of `enyo.Object`, any property (published or otherwise) is observable.  Also note that the long-form setters generated for published properties (e.g. `setPublicProperty`, for the example above internally call the generic `set()` function as well).

For programmaticly adding observers after your kind is created, you may use the `addObserver` and `removeObserver` functions supplied on `enyo.Object` (via the `enyo.ObserverSupport` mixin).

### Bindings

Bindings in Enyo are built on top of the basic observation capability above, and are responsible for propogating property value changes between two points: the source and target of the binding.  When the source of a binding changes, the new value is set to the target property.

You can declare bindings between properties in the scope of a component by adding entries to the `bindings` block of your kind.  In the example below, the value of the slider will be automatically set to the content of the label as the user drags the slider.  

```
enyo.kind({
	name: "MyValueSlider",
	components: [
		{kind: "moon.Slider", name:"slider"},
		{kind: "enyo.Control", name:"label"}
	],
	bindings: [
		{from: ".$.slider.value", to: ".$.label.content"}
	]
});
```
Note, the source (`from`) and target (`to`) properties of the binding are specified as string paths.  By convention, when the path starts with a dot (`.`) as in the example above, the path is relative to `this`.  If the path starts with a caret (`^`), the path is relative to the global scope.

By default, bindings are one-way, from the source to the target.  However, bindings can be specified as "two-way" by setting the `oneWay` flag to `false`:

```
enyo.kind({
	name: "MyValueSlider",
	published: {
		sliderValue: 10	// Initial value of slider
	},
	components: [
		{kind: "moon.Slider", name:"slider"},
		{kind: "enyo.Control", name:"label"}
	],
	bindings: [
		{from: ".sliderValue", to: ".$.slider.value", oneWay: false},	// two-way binding
		{from: ".$.slider.value", to: ".$.label.content"}				// one-way binding
	]
});
```

Note that with two-way bindings, the order of the `from` and `to` values still have meaning, since the initial value will be determined by the source (`from`) end.  In the example above, we are binding the `sliderValue` published property to the child slider's `value`, property.  At create time, the binding will propagate the value of the `sliderValue` published property to the slider's `value` property (not the other way around), but subsequent changes on the slider will be propagated from the slider's `value` back to the `sliderValue` published property.

An optional `transform` function may be provided on bindings to transform the value as it passes from the source to the target (or vice-versa, for two-way bindings):

```
enyo.kind({
	name: "MyValueSlider",
	components: [
		{kind: "moon.Slider", name:"slider", min: 0, max: 1},
		{kind: "enyo.Control", name:"label"}
	],
	bindings: [
		{from: ".$.slider.value", to: ".$.label.content", transform: function(val) {
			return "The slider value is " + Math.round(val * 100) + "%";
		}}
	]
});
```

If necessary, a bi-directional transform can be provided for two-way bindings by checking the second argument to the transform function to determine the direction the binding is firing: 

```
		{from: ".$.slider.value", to: ".$.input.value", oneWay:false, transform: function(val, dir) {
			if (this.dir == "source") {
				return (val * 100) + "%";
{'fraction_non_alphanumeric': 0.0936843579330626, 'fraction_numerical': 0.0022405825514633807, 'mean_word_length': 4.428734321550741, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4544986', 'n_tokens_mistral': 4017, 'n_tokens_neox': 3797, 'n_words': 1942}