Przeglądaj źródła

flatten binding structure

Evan You 11 lat temu
rodzic
commit
a242d2d325
2 zmienionych plików z 22 dodań i 53 usunięć
  1. 20 51
      src/instance/bindings.js
  2. 2 2
      src/watcher.js

+ 20 - 51
src/instance/bindings.js

@@ -3,50 +3,27 @@ var Path = require('../parse/path')
 var Observer = require('../observe/observer')
 
 /**
- * Setup the binding tree.
+ * Setup the bindings.
  *
- * Bindings form a tree-like structure that maps the Object
- * structure of observed data. However, only paths present
- * in the templates are created in the binding tree. When a
- * change event from the data observer arrives on the
- * instance, we traverse the binding tree along the changed
- * path to find the corresponding binding, and trigger
- * change for all its subscribers.
+ * Each accessed path in templates have a correspinding
+ * binding object. When a change is detected and emitted
+ * from the $observer, the corresponding binding notifies
+ * all its subscribing watchers to trigger updates.
  */
 
 exports._initBindings = function () {
-  var root = this._rootBinding = new Binding()
-  // the $data binding points to the root itself!
-  root._addChild('$data', root)
-  // point $parent and $root bindings to their
-  // repective owners.
-  if (this.$parent) {
-    root._addChild('$parent', this.$parent._rootBinding)
-    root._addChild('$root', this.$root._rootBinding)
-  }
+  this._bindings = Object.create(null)
+  this._createBindingAt('$data')
   // setup observer events
   this.$observer
     // simple updates
-    .on('set', this._updateBindingAt)
-    .on('mutate', this._updateBindingAt)
-    .on('delete', this._updateBindingAt)
+    .on('set', updateBindingAt)
+    .on('mutate', updateBindingAt)
+    .on('delete', updateBindingAt)
     // adding properties is a bit different
-    .on('add', this._updateAdd)
+    .on('add', updateAdd)
     // collect dependency
-    .on('get', this._collectDep)
-}
-
-/**
- * Retrive a binding at a given path.
- * If `create` is true, create all bindings that do not
- * exist yet along the way.
- *
- * @param {String} path
- * @return {Binding|undefined}
- */
-
-exports._getBindingAt = function (path) {
-  return Path.getFromObserver(this._rootBinding, path)
+    .on('get', collectDep)
 }
 
 /**
@@ -58,15 +35,7 @@ exports._getBindingAt = function (path) {
  */
 
 exports._createBindingAt = function (path) {
-  path = path.split(Observer.pathDelimiter)
-  var b = this._rootBinding
-  var child, key
-  for (var i = 0, l = path.length; i < l; i++) {
-    key = path[i]
-    child = b[key] || b._addChild(key)
-    b = child
-  }
-  return b
+  return this._bindings[path] = new Binding()
 }
 
 /**
@@ -78,13 +47,13 @@ exports._createBindingAt = function (path) {
  * @param {Boolean} fromScope
  */
 
-exports._updateBindingAt = function (path, k, v, fromScope) {
-  // root binding updates on any change,
+function updateBindingAt (path, k, v, fromScope) {
+  // the '$data' binding updates on any change,
   // but only if the change is not from parent scopes
   if (!fromScope) {
-    this._rootBinding._notify()
+    this._bindings.$data._notify()
   }
-  var binding = this._getBindingAt(path, true)
+  var binding = this._bindings[path]
   if (binding) {
     binding._notify()
   }
@@ -101,10 +70,10 @@ exports._updateBindingAt = function (path, k, v, fromScope) {
  * @param {String} path
  */
 
-exports._updateAdd = function (path) {
+function updateAdd (path) {
   var index = path.lastIndexOf(Observer.pathDelimiter)
   if (index > -1) path = path.slice(0, index)
-  this._updateBindingAt(path)
+  updateBindingAt.call(this, path)
 }
 
 /**
@@ -114,7 +83,7 @@ exports._updateAdd = function (path) {
  * @param {String} path
  */
 
-exports._collectDep = function (path) {
+function collectDep (path) {
   var watcher = this._activeWatcher
   // the get event might have come from a child vm's watcher
   // so this._activeWatcher is not guarunteed to be defined

+ 2 - 2
src/watcher.js

@@ -92,7 +92,7 @@ p.addDep = function (path) {
     newDeps[path] = true
     if (!oldDeps[path]) {
       var binding =
-        vm._getBindingAt(path) ||
+        vm._bindings[path] ||
         vm._createBindingAt(path)
       binding._addSub(this)
     }
@@ -186,7 +186,7 @@ p.teardown = function () {
     this.active = false
     var vm = this.vm
     for (var path in this.deps) {
-      vm._getBindingAt(path)._removeSub(this)
+      vm._bindings[path]._removeSub(this)
     }
   }
 }