Przeglądaj źródła

add directive deep option

Evan You 11 lat temu
rodzic
commit
1bbaab38bd
3 zmienionych plików z 40 dodań i 6 usunięć
  1. 2 1
      src/directive.js
  2. 24 4
      src/watcher.js
  3. 14 1
      test/unit/specs/directive_spec.js

+ 2 - 1
src/directive.js

@@ -85,7 +85,8 @@ p._bind = function (def) {
         this._watcherExp,
         this._watcherExp,
         update, // callback
         update, // callback
         this.filters,
         this.filters,
-        this.twoWay // need setter
+        this.twoWay, // need setter,
+        this.deep
       )
       )
     } else {
     } else {
       watcher.addCb(update)
       watcher.addCb(update)

+ 24 - 4
src/watcher.js

@@ -75,10 +75,11 @@ p.get = function () {
   } catch (e) {
   } catch (e) {
     _.warn(e)
     _.warn(e)
   }
   }
-  // use JSON.stringify to "touch" every property
-  // so they are all tracked as dependencies for
-  // deep watching
-  if (this.deep) JSON.stringify(value)
+  // "touch" every property so they are all tracked as
+  // dependencies for deep watching
+  if (this.deep) {
+    traverse(value)
+  }
   value = _.applyFilters(value, this.readFilters, vm)
   value = _.applyFilters(value, this.readFilters, vm)
   this.afterGet()
   this.afterGet()
   return value
   return value
@@ -214,4 +215,23 @@ p.teardown = function () {
   }
   }
 }
 }
 
 
+
+/**
+ * Recrusively traverse an object to evoke all converted
+ * getters, so that every nested property inside the object
+ * is collected as a "deep" dependency.
+ *
+ * @param {Object} obj
+ */
+
+function traverse (obj) {
+  var key, val
+  for (key in obj) {
+    val = obj[key]
+    if (_.isObject(val)) {
+      traverse(val)
+    }
+  }
+}
+
 module.exports = Watcher
 module.exports = Watcher

+ 14 - 1
test/unit/specs/directive_spec.js

@@ -15,7 +15,8 @@ describe('Directive', function () {
     }
     }
     vm = new Vue({
     vm = new Vue({
       data:{
       data:{
-        a:1
+        a:1,
+        b: { c: 2 }
       },
       },
       filters: {
       filters: {
         test: function (v) {
         test: function (v) {
@@ -148,6 +149,18 @@ describe('Directive', function () {
     })
     })
   })
   })
 
 
+  it('deep', function (done) {
+    def.deep = true
+    var d = new Directive('test', el, vm, {
+      expression: 'b'
+    }, def)
+    vm.b.c = 3
+    nextTick(function () {
+      expect(def.update.calls.count()).toBe(2)
+      done()
+    })
+  })
+
   it('function def', function () {
   it('function def', function () {
     var d = new Directive('test', el, vm, {
     var d = new Directive('test', el, vm, {
       expression: 'a'
       expression: 'a'