Ver código fonte

directly use array length

Evan You 12 anos atrás
pai
commit
77ce1fc355
4 arquivos alterados com 77 adições e 15 exclusões
  1. 40 0
      examples/repeated-items.html
  2. 20 5
      src/compiler.js
  3. 5 6
      src/directives/each.js
  4. 12 4
      src/observer.js

+ 40 - 0
examples/repeated-items.html

@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html lang="en">
+    <head>
+        <title>SEED repeated items</title>
+        <meta charset="utf-8">
+    </head>
+    <body>
+        <div id="app">
+            <ul>
+                <li sd-each="item:items" sd-text="item.title"></li>
+            </ul>
+            <p>Total items: {{items.length}}</p>
+        </div>
+        <script src="../dist/seed.js"></script>
+        <script>
+
+            seed.config({debug: true})
+
+            var items = [
+                { title: 'hi' },
+                { title: 'ha' },
+                { title: 'hu' },
+                { title: 'ho' },
+                { title: 'he' }
+            ]
+
+            var test = {
+                test: [1, 2, 3]
+            }
+
+            var demo = new seed.ViewModel({
+                el: '#app',
+                data: {
+                    items: items,
+                    test: test
+                }
+            })
+        </script>
+    </body>
+</html>

+ 20 - 5
src/compiler.js

@@ -73,6 +73,7 @@ function Compiler (vm, options) {
     var observables = this.observables = []
     var computed = this.computed = [] // computed props to parse deps from
     var ctxBindings = this.contextBindings = [] // computed props with dynamic context
+    var arrays = this.arrays = []
 
     // prototypal inheritance of bindings
     var parent = this.parentCompiler
@@ -113,12 +114,18 @@ function Compiler (vm, options) {
         binding = observables[i]
         Observer.observe(binding.value, binding.key, this.observer)
     }
+    // emit set events for array lengths
+    i = arrays.length
+    while (i--) {
+        binding = arrays[i]
+        this.observer.emit('set', binding.key + '.length', binding.value.length)
+    }
     // extract dependencies for computed properties
     if (computed.length) DepsParser.parse(computed)
     // extract dependencies for computed properties with dynamic context
     if (ctxBindings.length) this.bindContexts(ctxBindings)
-
-    this.observables = this.computed = this.contextBindings = null
+    // unset these no longer needed stuff
+    this.observables = this.computed = this.contextBindings = this.arrays = null
 }
 
 var CompilerProto = Compiler.prototype
@@ -141,14 +148,17 @@ CompilerProto.setupObserver = function () {
     // add own listeners which trigger binding updates
     observer
         .on('get', function (key) {
-            if (depsOb.isObserving && bindings[key]) {
+            console.log('get ' + key)
+            if (bindings[key] && depsOb.isObserving) {
                 depsOb.emit('get', bindings[key])
             }
         })
         .on('set', function (key, val) {
+            console.log('set ' + key)
             if (bindings[key]) bindings[key].update(val)
         })
         .on('mutate', function (key) {
+            console.log('mutate ' + key)
             if (bindings[key]) bindings[key].pub()
         })
 }
@@ -300,7 +310,9 @@ CompilerProto.bindDirective = function (directive) {
     }
 
     // set initial value
-    directive.update(binding.value)
+    if (binding.value) {
+        directive.update(binding.value)
+    }
     if (binding.isComputed) {
         directive.refresh()
     }
@@ -375,13 +387,16 @@ CompilerProto.define = function (key, binding) {
             this.computed.push(binding)
         } else {
             // observe objects later, becase there might be more keys
-            // to be added to it
+            // to be added to it. we also want to emit all the set events
+            // when values are available.
             this.observables.push(binding)
         }
     } else if (type === 'Array') {
         // observe arrays right now, because they will be needed in
         // sd-each directives.
         Observer.observe(value, key, compiler.observer)
+        // we need to later emit set event for the arrays length.
+        this.arrays.push(binding)
     }
 
     Object.defineProperty(vm, key, {

+ 5 - 6
src/directives/each.js

@@ -83,7 +83,7 @@ module.exports = {
         ctn.removeChild(this.el)
         this.collection = null
         this.vms = null
-        this.mutationListener = (function (mutation) {
+        this.mutationListener = (function (path, arr, mutation) {
             mutationHandlers[mutation.method].call(this, mutation)
         }).bind(this)
     },
@@ -102,7 +102,6 @@ module.exports = {
         this.collection = collection
         this.vms = []
 
-        console.log(collection)
         // listen for collection mutation events
         // the collection has been augmented during Binding.set()
         collection.__observer__.on('mutate', this.mutationListener)
@@ -120,16 +119,16 @@ module.exports = {
         this.container.insertBefore(node, ref)
         ViewModel = ViewModel || require('../viewmodel')
         var vmID = node.getAttribute(config.prefix + '-viewmodel'),
-            ChildVM = utils.getVM(vmID) || ViewModel
+            ChildVM = utils.getVM(vmID) || ViewModel,
+            wrappedData = {}
+        wrappedData[this.arg] = data
         var item = new ChildVM({
             el: node,
             each: true,
             eachPrefix: this.arg,
             parentCompiler: this.compiler,
             delegator: this.container,
-            data: {
-                todo: data
-            }
+            data: wrappedData
         })
         if (dummy) {
             item.$destroy()

+ 12 - 4
src/observer.js

@@ -101,10 +101,10 @@ function emitSet (obj, observer) {
 
 module.exports = {
 
-    observe: function (obj, path, observer) {
+    observe: function (obj, rawPath, observer) {
         if (isWatchable(obj)) {
-            path = path + '.'
-            var ob, alreadyConverted = !!obj.__observer__
+            var path = rawPath + '.',
+                ob, alreadyConverted = !!obj.__observer__
             if (!alreadyConverted) {
                 defProtected(obj, '__observer__', new Emitter())
             }
@@ -117,7 +117,15 @@ module.exports = {
                     observer.emit('set', path + key, val)
                 },
                 mutate: function (key, val, mutation) {
-                    observer.emit('mutate', path + key, val, mutation)
+                    // if the Array is a root value
+                    // the key will be null
+                    var fixedPath = key ? path + key : rawPath
+                    observer.emit('mutate', fixedPath, val, mutation)
+                    // also emit set for Array's length when it mutates
+                    var m = mutation.method
+                    if (m !== 'sort' && m !== 'reverse') {
+                        observer.emit('set', fixedPath + '.length', val.length)
+                    }
                 }
             }
             ob