فهرست منبع

fix watcher unregister

Evan You 11 سال پیش
والد
کامیت
56637f89de
5فایلهای تغییر یافته به همراه36 افزوده شده و 77 حذف شده
  1. 13 20
      src/api/data.js
  2. 1 1
      src/compile/transclude.js
  3. 11 19
      src/directive.js
  4. 4 10
      src/watcher.js
  5. 7 27
      test/unit/specs/watcher_spec.js

+ 13 - 20
src/api/data.js

@@ -67,35 +67,28 @@ exports.$delete = function (key) {
  * @param {String} exp
  * @param {Function} cb
  * @param {Boolean} [immediate]
+ * @return {Function} - unwatchFn
  */
 
 exports.$watch = function (exp, cb, immediate) {
-  var watcher = this._userWatchers[exp]
+  var vm = this
+  var watcher = vm._userWatchers[exp]
+  var wrappedCb = function (val, oldVal) {
+    cb.call(vm, val, oldVal)
+  }
   if (!watcher) {
-    watcher =
-    this._userWatchers[exp] =
-      new Watcher(this, exp, cb, this)
+    watcher = vm._userWatchers[exp] =
+      new Watcher(vm, exp, wrappedCb)
   } else {
-    watcher.addCb(cb, this)
+    watcher.addCb(wrappedCb)
   }
   if (immediate) {
-    cb.call(this, watcher.value)
+    wrappedCb(watcher.value)
   }
-}
-
-/**
- * Teardown a watcher with given id.
- *
- * @param {String} exp
- * @param {Function} cb
- */
-
-exports.$unwatch = function (exp, cb) {
-  var watcher = this._userWatchers[exp]
-  if (watcher) {
-    watcher.removeCb(cb)
+  return function unwatchFn () {
+    watcher.removeCb(wrappedCb)
     if (!watcher.active) {
-      this._userWatchers[exp] = null
+      vm._userWatchers[exp] = null
     }
   }
 }

+ 1 - 1
src/compile/transclude.js

@@ -13,7 +13,7 @@ var templateParser = require('../parse/template')
  * @return {Element|DocumentFragment}
  */
 
-var transclude = module.exports = function (el, options) {
+module.exports = function transclude (el, options) {
   if (typeof el === 'string') {
     var selector = el
     el = document.querySelector(el)

+ 11 - 19
src/directive.js

@@ -63,18 +63,24 @@ p._bind = function (def) {
   ) {
     if (!this._checkExpFn()) {
       var exp = this._watcherExp
-      var wathcer = this.vm._watchers[exp]
-      if (!wathcer) {
+      var watcher = this.vm._watchers[exp]
+      // wrapped updater for context
+      var dir = this
+      var update = this._update = function (val, oldVal) {
+        if (!dir._locked) {
+          dir.update(val, oldVal)
+        }
+      }
+      if (!watcher) {
         watcher = this.vm._watchers[exp] = new Watcher(
           this.vm,
           exp,
-          this._update, // callback
-          this, // callback context
+          update, // callback
           this.filters,
           this.twoWay // need setter
         )
       } else {
-        watcher.addCb(this._update, this)
+        watcher.addCb(update)
       }
       this._watcher = watcher
       this.update(watcher.value)
@@ -137,20 +143,6 @@ p._checkExpFn = function () {
   }
 }
 
-/**
- * Callback for the watcher.
- * Check locked or not before calling definition update.
- *
- * @param {*} value
- * @param {*} oldValue
- */
-
-p._update = function (value, oldValue) {
-  if (!this._locked) {
-    this.update(value, oldValue)
-  }
-}
-
 /**
  * Teardown the watcher and call unbind.
  */

+ 4 - 10
src/watcher.js

@@ -15,17 +15,15 @@ var uid = 0
  * @param {Vue} vm
  * @param {String} expression
  * @param {Function} cb
- * @oaram {Object} ctx
  * @param {Array} [filters]
  * @param {Boolean} [needSet]
  * @constructor
  */
 
-function Watcher (vm, expression, cb, ctx, filters, needSet) {
+function Watcher (vm, expression, cb, filters, needSet) {
   this.vm = vm
   this.expression = expression
   this.cbs = [cb]
-  this.ctxs = [ctx]
   this.id = ++uid // uid for batching
   this.value = undefined
   this.active = true
@@ -174,9 +172,8 @@ p.run = function () {
       var oldValue = this.value
       this.value = value
       var cbs = this.cbs
-      var ctxs = this.ctxs
       for (var i = 0, l = cbs.length; i < l; i++) {
-        cbs[i].call(ctxs[i], value, oldValue)
+        cbs[i](value, oldValue)
       }
     }
   }
@@ -186,12 +183,10 @@ p.run = function () {
  * Add a callback.
  *
  * @param {Function} cb
- * @param {Object} ctx
  */
 
-p.addCb = function (cb, ctx) {
+p.addCb = function (cb) {
   this.cbs.push(cb)
-  this.ctxs.push(ctx)
 }
 
 /**
@@ -206,7 +201,6 @@ p.removeCb = function (cb) {
     var i = cbs.indexOf(cb)
     if (i > -1) {
       cbs.splice(i, 1)
-      this.ctxs.splice(i, 1)
     }
   } else if (cb === cbs[0]) {
     this.teardown()
@@ -224,7 +218,7 @@ p.teardown = function () {
     for (var path in this.deps) {
       vm._bindings[path]._removeSub(this)
     }
-    this.vm = this.cbs = this.ctxs = null
+    this.vm = this.cbs = null
   }
 }
 

+ 7 - 27
test/unit/specs/watcher_spec.js

@@ -195,19 +195,6 @@ describe('Watcher', function () {
     })
   })
 
-  it('callback context', function (done) {
-    var context = {}
-    var watcher = new Watcher(vm, 'b.c', function () {
-      spy.apply(this, arguments)
-      expect(this).toBe(context)
-    }, context)
-    vm.b.c = 3
-    nextTick(function () {
-      expect(spy).toHaveBeenCalledWith(3, 2)
-      done()
-    })
-  })
-
   it('filters', function (done) {
     vm.$options.filters.test = function (val, multi) {
       return val * multi
@@ -215,7 +202,7 @@ describe('Watcher', function () {
     vm.$options.filters.test2 = function (val, str) {
       return val + str
     }
-    var watcher = new Watcher(vm, 'b.c', spy, null, [
+    var watcher = new Watcher(vm, 'b.c', spy, [
       { name: 'test', args: [3] },
       { name: 'test2', args: ['yo']}
     ])
@@ -234,7 +221,7 @@ describe('Watcher', function () {
         return val > arg ? val : oldVal
       }
     }
-    var watcher = new Watcher(vm, 'b["c"]', spy, null, [
+    var watcher = new Watcher(vm, 'b["c"]', spy, [
       { name: 'test', args: [5] }
     ], true)
     expect(watcher.value).toBe(2)
@@ -266,18 +253,13 @@ describe('Watcher', function () {
   })
 
   it('add callback', function (done) {
-    var ctx1 = {}
-    var ctx2 = {}
-    var watcher = new Watcher(vm, 'a', function () {
-      this.called = 1
-    }, ctx1)
-    watcher.addCb(function () {
-      this.called = 2
-    }, ctx2)
+    var watcher = new Watcher(vm, 'a', spy)
+    var spy2 = jasmine.createSpy()
+    watcher.addCb(spy2)
     vm.a = 99
     nextTick(function () {
-      expect(ctx1.called).toBe(1)
-      expect(ctx2.called).toBe(2)
+      expect(spy).toHaveBeenCalledWith(99, 1)
+      expect(spy2).toHaveBeenCalledWith(99, 1)
       done()
     })
   })
@@ -290,7 +272,6 @@ describe('Watcher', function () {
     expect(watcher.active).toBe(false)
     expect(watcher.vm).toBe(null)
     expect(watcher.cbs).toBe(null)
-    expect(watcher.ctxs).toBe(null)
     // multiple
     watcher = new Watcher(vm, 'a', spy)
     var spy2 = jasmine.createSpy()
@@ -312,7 +293,6 @@ describe('Watcher', function () {
       expect(watcher.active).toBe(false)
       expect(watcher.vm).toBe(null)
       expect(watcher.cbs).toBe(null)
-      expect(watcher.ctxs).toBe(null)
       expect(spy.calls.count()).toBe(0)
       done()
     })