Browse Source

fix v-for alias two-way binding warning

Evan You 10 years ago
parent
commit
bb310c79c4
2 changed files with 16 additions and 13 deletions
  1. 7 5
      src/directives/for.js
  2. 9 8
      src/watcher.js

+ 7 - 5
src/directives/for.js

@@ -7,14 +7,16 @@ var uid = 0
 module.exports = {
 
   bind: function () {
+    // determine alias
+    this.alias = this.arg
     // support "item in items" syntax
     var inMatch = this.expression.match(/(.*) in (.*)/)
     if (inMatch) {
-      this.arg = inMatch[1]
+      this.alias = inMatch[1]
       this._watcherExp = inMatch[2]
     }
 
-    if (!this.arg) {
+    if (!this.alias) {
       process.env.NODE_ENV !== 'production' && _.warn(
         'Alias is required in v-for.'
       )
@@ -74,7 +76,7 @@ module.exports = {
     var converted = this.converted
     var oldFrags = this.frags
     var frags = this.frags = new Array(data.length)
-    var alias = this.arg
+    var alias = this.alias
     var start = this.start
     var end = this.end
     var inDoc = _.inDoc(start)
@@ -176,8 +178,8 @@ module.exports = {
     var scope = Object.create(parentScope)
     // make sure point $parent to parent scope
     scope.$parent = parentScope
-    scope.$alias = alias
-    scope.$source = this.rawValue
+    // for two-way binding on alias
+    scope.$forContext = this
     // define scope properties
     _.defineReactive(scope, alias, value)
     _.defineReactive(scope, '$index', index)

+ 9 - 8
src/watcher.js

@@ -145,21 +145,22 @@ Watcher.prototype.set = function (value) {
     }
   }
   // two-way sync for v-for alias
-  if (scope.$alias === this.expression) {
-    if (this.filters) {
+  var forContext = scope.$forContext
+  if (forContext && forContext.alias === this.expression) {
+    if (forContext.filters) {
       process.env.NODE_ENV !== 'production' && _.warn(
         'It seems you are using two-way binding on ' +
-        'a v-for alias, and the v-for is also filtered. ' +
-        'This will not work properly. Please use an ' +
-        'array of objects and bind to object properties ' +
-        'instead.'
+        'a v-for alias, and the v-for has filters. ' +
+        'This will not work properly. Either remove the ' +
+        'filters or use an array of objects and bind to ' +
+        'object properties instead.'
       )
       return
     }
     if (scope.$key) { // original is an object
-      scope.$source[scope.$key] = value
+      forContext.rawValue[scope.$key] = value
     } else {
-      scope.$source.$set(scope.$index, value)
+      forContext.rawValue.$set(scope.$index, value)
     }
   }
 }