From 523d117fb5ccdd6b2cef900736ab6aa7ae739704 Mon Sep 17 00:00:00 2001 From: Jeremy Zagorski Date: Fri, 21 Sep 2018 11:56:11 -0400 Subject: [PATCH] docs(how-it-works): Add sentences about observed props added during binding Aurelia Binding adds the observing property to source object when it does not exist for a few of the binding commands. This can be confusing for state management applications that might have a very large state and do not define every single property on their initial state. After binding runs in the view model, their state now has defined properties that were not on an initial state. I think it is important to document this since state management (like aurelia-store) are becoming popular. closes #713 --- doc/article/en-US/binding-how-it-works.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/article/en-US/binding-how-it-works.md b/doc/article/en-US/binding-how-it-works.md index dcfb340f..32dec611 100644 --- a/doc/article/en-US/binding-how-it-works.md +++ b/doc/article/en-US/binding-how-it-works.md @@ -20,7 +20,7 @@ Creating a binding instance is accomplished by invoking the `createBinding` meth Once the ViewFactory's `create` method has finished executing all the instructions and creating all the bindings it will instantiate the `View`, whose constructor will receive the DOM element, bindings, controllers, and a few other items. With the View created the Controller can execute the view's `bind` method, passing in the binding context and override context. The binding context and override context tuple is known as the `scope`- more on that in a minute... -The view's `bind` method loops through all of its binding instances and calls their `bind` method, passing in the binding context and override context. This is where the AST in the binding's `sourceExpression` becomes important. The abstract syntax tree is the heart of the binding system. It is the object representation of your binding's JavaScript expression. Each node in the tree is an implementation of a very binding-specific interface. There are about 20 different AST node types, each tailored to a particular type of JavaScript expression. The AST can be evaluated by calling the root AST node's `evaluate` method and passing in the `scope`. Each node in the AST knows how to evaluate its piece of the expression using the scope and the end result will be the value of the JavaScript expression. After the binding gets the model value by evaluating the `sourceExpression` it assigns this value to the view by calling the `targetObserver`'s `setValue` method. Next the binding will check its binding mode. If it is `one-time`, there is nothing left to do. If it is `to-view` or `two-way` the binding will use the AST's `connect` method to subscribe to changes in the view-model. Each node in the AST knows which view-model properties to observe and will use the ObserverLocator to create property observers to subscribe to property change events. Finally, if the binding mode is `two-way` the binding will call the `targetObserver`'s subscribe method. +The view's `bind` method loops through all of its binding instances and calls their `bind` method, passing in the binding context and override context. This is where the AST in the binding's `sourceExpression` becomes important. The abstract syntax tree is the heart of the binding system. It is the object representation of your binding's JavaScript expression. Each node in the tree is an implementation of a very binding-specific interface. There are about 20 different AST node types, each tailored to a particular type of JavaScript expression. The AST can be evaluated by calling the root AST node's `evaluate` method and passing in the `scope`. Each node in the AST knows how to evaluate its piece of the expression using the scope and the end result will be the value of the JavaScript expression. After the binding gets the model value by evaluating the `sourceExpression` it assigns this value to the view by calling the `targetObserver`'s `setValue` method. Next the binding will check its binding mode. If it is `one-time`, there is nothing left to do. If it is `to-view` or `two-way` the binding will use the AST's `connect` method to subscribe to changes in the view-model. Each node in the AST knows which view-model properties to observe and will use the ObserverLocator to create property observers to subscribe to property change events. Finally, if the binding mode is `two-way` the binding will call the `targetObserver`'s subscribe method. Since `two-way`, `one-way` and `to-view` all require observers, property interceptors need to be added during binding to detect changes. By default, the intercepted property will be added to the view model or view model property with an `undefined` value if not already defined on the object (e.g. `value.bind="foo"` will create the `foo` property on the view model if it does not exist and `value.bind="foo.bar"` will create the `bar` property on the `foo` object if the `bar` property is not already defined on `foo`). At this point the view and view-model are data-bound. When changes occur in the model, the property observers created when the AST was `connect`ed will fire change events, triggering the binding to update the target by calling `targetObserver.setValue`. When changes occur in the view the property observer known as the `targetObserver` will trigger the binding to update the source by calling `sourceExpression.assign(scope, value)`. All that remains is for the Controller to `attach` the view to the DOM. Later, when the view is no longer needed it will be `detached` from the DOM and `unbind` will be invoked, unbinding all the views, which will unsubscribe all the property observers.