Procházet zdrojové kódy

separate deps-parser

Evan You před 13 roky
rodič
revize
e762cc7ed5
4 změnil soubory, kde provedl 56 přidání a 54 odebrání
  1. 1 0
      component.json
  2. 12 4
      src/binding.js
  3. 40 0
      src/deps-parser.js
  4. 3 50
      src/seed.js

+ 1 - 0
component.json

@@ -9,6 +9,7 @@
     "src/binding.js",
     "src/directive.js",
     "src/text-parser.js",
+    "src/deps-parser.js",
     "src/filters.js",
     "src/directives/index.js",
     "src/directives/each.js",

+ 12 - 4
src/binding.js

@@ -1,4 +1,5 @@
-var Emitter  = require('emitter')
+var Emitter  = require('emitter'),
+    observer = require('./deps-parser').observer
 
 /*
  *  Binding class.
@@ -46,14 +47,21 @@ Binding.prototype.defineAccessors = function (seed, key) {
     var self = this
     Object.defineProperty(seed.scope, key, {
         get: function () {
-            seed.emit('get', key)
+            if (observer.isObserving) {
+                observer.emit('get', self)
+            }
             return self.isComputed
                 ? self.value.get()
                 : self.value
         },
         set: function (value) {
-            if (self.isComputed && self.value.set) {
-                self.value.set(value)
+            if (self.isComputed) {
+                // computed properties cannot be redefined
+                // no need to call binding.update() here,
+                // as dependency extraction has taken care of that
+                if (self.value.set) {
+                    self.value.set(value)
+                }
             } else if (value !== self.value) {
                 self.value = value
                 self.update(value)

+ 40 - 0
src/deps-parser.js

@@ -0,0 +1,40 @@
+var Emitter  = require('emitter'),
+    observer = new Emitter()
+
+/*
+ *  Auto-extract the dependencies of a computed property
+ *  by recording the getters triggered when evaluating it.
+ *
+ *  However, the first pass will contain duplicate dependencies
+ *  for computed properties. It is therefore necessary to do a
+ *  second pass in injectDeps()
+ */
+function catchDeps (binding) {
+    observer.on('get', function (dep) {
+        binding.dependencies.push(dep)
+    })
+    binding.value.get()
+    observer.off('get')
+}
+
+/*
+ *  The second pass of dependency extraction.
+ *  Only include dependencies that don't have dependencies themselves.
+ */
+function injectDeps (binding) {
+    binding.dependencies.forEach(function (dep) {
+        if (!dep.dependencies.length) {
+            dep.dependents.push.apply(dep.dependents, binding.instances)
+        }
+    })
+}
+
+module.exports = {
+    observer: observer,
+    parse: function (bindings) {
+        observer.isObserving = true
+        bindings.forEach(catchDeps)
+        bindings.forEach(injectDeps)
+        observer.isObserving = false
+    }
+}

+ 3 - 50
src/seed.js

@@ -1,16 +1,13 @@
 var config          = require('./config'),
-    Emitter         = require('emitter'),
     Binding         = require('./binding'),
     Directive       = require('./directive'),
-    TextParser      = require('./text-parser')
+    TextParser      = require('./text-parser'),
+    depsParser      = require('./deps-parser')
 
 var slice           = Array.prototype.slice,
     ctrlAttr        = config.prefix + '-controller',
     eachAttr        = config.prefix + '-each'
 
-var depsObserver    = new Emitter(),
-    parsingDeps     = false
-
 /*
  *  The main ViewModel class
  *  scans a node and parse it to populate data bindings
@@ -71,26 +68,12 @@ function Seed (el, options) {
         }
     }
 
-    // add event listener to update corresponding binding
-    var self = this
-    this.on('get', function (key) {
-        if (parsingDeps) {
-            depsObserver.emit('get', self._bindings[key])
-        }
-    })
-    this.on('set', function (key, value) {
-        self._bindings[key].update(value)
-    })
-
     // now parse the DOM
     this._compileNode(el, true)
 
     // extract dependencies for computed properties
-    parsingDeps = true
-    this._computed.forEach(parseDeps)
-    this._computed.forEach(injectDeps)
+    depsParser.parse(this._computed)
     delete this._computed
-    parsingDeps = false
 }
 
 /*
@@ -269,34 +252,6 @@ Seed.prototype._dump = function () {
 
 // Helpers --------------------------------------------------------------------
 
-/*
- *  Auto-extract the dependencies of a computed property
- *  by recording the getters triggered when evaluating it.
- *
- *  However, the first pass will contain duplicate dependencies
- *  for computed properties. It is therefore necessary to do a
- *  second pass in injectDeps()
- */
-function parseDeps (binding) {
-    depsObserver.on('get', function (dep) {
-        binding.dependencies.push(dep)
-    })
-    binding.value.get()
-    depsObserver.off('get')
-}
-
-/*
- *  The second pass of dependency extraction.
- *  Only include dependencies that don't have dependencies themselves.
- */
-function injectDeps (binding) {
-    binding.dependencies.forEach(function (dep) {
-        if (!dep.dependencies || !dep.dependencies.length) {
-            dep.dependents.push.apply(dep.dependents, binding.instances)
-        }
-    })
-}
-
 /*
  *  determine which scope a key belongs to based on nesting symbols
  */
@@ -314,6 +269,4 @@ function getScopeOwner (key, seed) {
     return seed
 }
 
-Emitter(Seed.prototype)
-
 module.exports = Seed