Evan You 12 سال پیش
والد
کامیت
88513c077d
5فایلهای تغییر یافته به همراه82 افزوده شده و 41 حذف شده
  1. 3 3
      examples/todos.html
  2. 2 3
      src/directive-parser.js
  3. 72 29
      src/directives/each.js
  4. 4 6
      src/directives/on.js
  5. 1 0
      src/seed.js

+ 3 - 3
examples/todos.html

@@ -94,12 +94,12 @@
                 }
 
                 scope.removeTodo = function (e) {
-                    scope.todos.splice(e.seed.index, 1)
-                    scope.remaining -= e.seed.scope.done ? 0 : 1
+                    scope.todos.splice(e.scope.$index, 1)
+                    scope.remaining -= e.scope.done ? 0 : 1
                 }
 
                 scope.toggleTodo = function (e) {
-                    scope.remaining += e.seed.scope.done ? -1 : 1
+                    scope.remaining += e.scope.done ? -1 : 1
                 }
 
                 scope.setFilter = function (e) {

+ 2 - 3
src/directive-parser.js

@@ -6,8 +6,7 @@ var KEY_RE          = /^[^\|<]+/,
     ARG_RE          = /([^:]+):(.+)$/,
     FILTERS_RE      = /\|[^\|<]+/g,
     FILTER_TOKEN_RE = /[^\s']+|'[^']+'/g,
-    DEPS_RE         = /<[^<\|]+/g,
-    QUOTE_RE        = /'/g
+    DEPS_RE         = /<[^<\|]+/g
 
 function Directive (directiveName, expression) {
 
@@ -44,7 +43,7 @@ function Directive (directiveName, expression) {
             var tokens = filter.slice(1)
                 .match(FILTER_TOKEN_RE)
                 .map(function (token) {
-                    return token.replace(QUOTE_RE, '').trim()
+                    return token.replace(/'/g, '').trim()
                 })
             return {
                 name  : tokens[0],

+ 72 - 29
src/directives/each.js

@@ -1,25 +1,64 @@
 var config = require('../config')
 
-var proto = Array.prototype,
-    slice = proto.slice,
-    mutatorMethods = [
-        'pop',
-        'push',
-        'reverse',
-        'shift',
-        'unshift',
-        'splice',
-        'sort'
-    ]
+var mutationHandlers = {
+    push: function (m) {
+        var self = this
+        m.args.forEach(function (data, i) {
+            var seed = self.buildItem(data, self.collection.length + i)
+            self.container.insertBefore(seed.el, self.marker)
+        })
+    },
+    pop: function (m) {
+        m.result.$destroy()
+    },
+    unshift: function (m) {
+        var self = this
+        m.args.forEach(function (data, i) {
+            var seed = self.buildItem(data, i)
+            self.container.insertBefore(seed.el, self.collection[m.args.length].$seed.el)
+        })
+        self.reorder()
+    },
+    shift: function (m) {
+        m.result.$destroy()
+        var self = this
+        self.reorder()
+    },
+    splice: function (m) {
+        var self = this
+        m.result.forEach(function (scope) {
+            scope.$destroy()
+        })
+        if (m.args.length > 2) {
+            m.args.slice(2).forEach(function (data, i) {
+                var seed  = self.buildItem(data, i),
+                    index = m.args[0] - m.args[1] + (m.args.length - 1),
+                    ref   = self.collection[index]
+                          ? self.collection[index].$seed.el
+                          : self.marker
+                self.container.insertBefore(seed.el, ref)
+            })
+        }
+        self.reorder()
+    },
+    sort: function () {
+        var self = this
+        self.collection.forEach(function (scope, i) {
+            scope.$index = i
+            self.container.insertBefore(scope.$seed.el, self.marker)
+        })
+    }
+}
+mutationHandlers.reverse = mutationHandlers.sort
 
 function watchArray (arr, callback) {
-    mutatorMethods.forEach(function (method) {
+    Object.keys(mutationHandlers).forEach(function (method) {
         arr[method] = function () {
-            proto[method].apply(this, arguments)
+            var result = Array.prototype[method].apply(this, arguments)
             callback({
-                event: method,
-                args: slice.call(arguments),
-                array: arr
+                method: method,
+                args: Array.prototype.slice.call(arguments),
+                result: result
             })
         }
     })
@@ -33,21 +72,23 @@ module.exports = {
         this.marker = document.createComment('sd-each-' + this.arg)
         ctn.insertBefore(this.marker, this.el)
         ctn.removeChild(this.el)
-        this.childSeeds = []
     },
 
     update: function (collection) {
         this.unbind(true)
-        this.childSeeds = []
         if (!Array.isArray(collection)) return
-        watchArray(collection, this.mutate.bind(this))
+        this.collection = collection
         var self = this
-        collection.forEach(function (item, i) {
-            self.childSeeds.push(self.buildItem(item, i, collection))
+        watchArray(collection, function (mutation) {
+            mutationHandlers[mutation.method].call(self, mutation)
+        })
+        collection.forEach(function (data, i) {
+            var seed = self.buildItem(data, i)
+            self.container.insertBefore(seed.el, self.marker)
         })
     },
 
-    buildItem: function (data, index, collection) {
+    buildItem: function (data, index) {
         var Seed = require('../seed'),
             node = this.el.cloneNode(true)
         var spore = new Seed(node, {
@@ -57,21 +98,23 @@ module.exports = {
                 index: index,
                 data: data
             })
-        this.container.insertBefore(node, this.marker)
-        collection[index] = spore.scope
+        this.collection[index] = spore.scope
         return spore
     },
 
-    mutate: function (mutation) {
-        console.log(mutation)
+    reorder: function () {
+        this.collection.forEach(function (scope, i) {
+            scope.$index = i
+        })
     },
 
     unbind: function (rm) {
-        if (this.childSeeds.length) {
+        if (this.collection && this.collection.length) {
             var fn = rm ? '_destroy' : '_unbind'
-            this.childSeeds.forEach(function (child) {
-                child[fn]()
+            this.collection.forEach(function (scope) {
+                scope.$seed[fn]()
             })
+            this.collection = null
         }
     }
 }

+ 4 - 6
src/directives/on.js

@@ -48,10 +48,9 @@ module.exports = {
                     var target = delegateCheck(e.target, delegator, selector)
                     if (target) {
                         handler({
-                            el            : target,
                             originalEvent : e,
-                            directive     : self,
-                            seed          : target.seed
+                            el            : target,
+                            scope         : target.seed.scope
                         })
                     }
                 }
@@ -63,10 +62,9 @@ module.exports = {
             // a normal handler
             this.handler = function (e) {
                 handler({
-                    el            : e.currentTarget,
                     originalEvent : e,
-                    directive     : self,
-                    seed          : self.seed
+                    el            : e.currentTarget,
+                    scope         : self.seed.scope
                 })
             }
             this.el.addEventListener(event, this.handler)

+ 1 - 0
src/seed.js

@@ -35,6 +35,7 @@ function Seed (el, options) {
     this.scope.$destroy = this._destroy.bind(this)
     this.scope.$dump    = this._dump.bind(this)
     this.scope.$index   = options.index
+    this.scope.$parent  = options.parentSeed && options.parentSeed.scope
 
     // revursively process nodes for directives
     this._compileNode(el, true)