Evan You 12 лет назад
Родитель
Сommit
b379274b31
6 измененных файлов с 25 добавлено и 16 удалено
  1. 2 2
      examples/todomvc/index.html
  2. 4 7
      examples/todomvc/js/app.js
  3. 3 1
      src/compiler.js
  4. 1 1
      src/directives/index.js
  5. 1 1
      src/directives/on.js
  6. 14 4
      src/exp-parser.js

+ 2 - 2
examples/todomvc/index.html

@@ -29,7 +29,7 @@
                         class="todo"
                         sd-each="todo:todos"
                         sd-show="todoFilter(todo)"
-                        sd-class="completed:todo.completed, editing:todo.editing"
+                        sd-class="completed:todo.completed, editing:editedTodo===todo"
                     >
                         <div class="view">
                             <input
@@ -44,7 +44,7 @@
                         <input
                             class="edit"
                             type="text"
-                            sd-focus="todo.editing"
+                            sd-focus="editedTodo===todo"
                             sd-on="blur:doneEdit, keyup:doneEdit | key enter, keyup:cancelEdit | key esc"
                             sd-value="todo.title"
                         >

+ 4 - 7
examples/todomvc/js/app.js

@@ -1,7 +1,4 @@
-seed.config({ debug: false })
-
 var filters = {
-    // need to access todo.completed in here so Seed.js can capture dependency.
     all: function (todo) { return todo.completed || true },
     active: function (todo) { return !todo.completed },
     completed: function (todo) { return todo.completed }
@@ -46,19 +43,19 @@ var Todos = seed.ViewModel.extend({
 
         editTodo: function (e) {
             this.beforeEditCache = e.item.title
-            e.item.editing = true
+            this.editedTodo = e.item
         },
 
         doneEdit: function (e) {
-            if (!e.item.editing) return
-            e.item.editing = false
+            if (!this.editedTodo) return
+            this.editedTodo = null
             e.item.title = e.item.title.trim()
             if (!e.item.title) this.removeTodo(e)
             todoStorage.save()
         },
 
         cancelEdit: function (e) {
-            e.item.editing = false
+            this.editedTodo = null
             e.item.title = this.beforeEditCache
         },
 

+ 3 - 1
src/compiler.js

@@ -391,7 +391,9 @@ CompilerProto.define = function (key, binding) {
         enumerable: true,
         get: function () {
             var value = binding.value
-            if ((!binding.isComputed && (value === undefined || !value.__observer__)) || Array.isArray(value)) {
+            if ((!binding.isComputed &&
+                (value === undefined || value === null || !value.__observer__)) ||
+                Array.isArray(value)) {
                 // only emit non-computed, non-observed (tip) values, or Arrays.
                 // because these are the cleanest dependencies
                 compiler.observer.emit('get', key)

+ 1 - 1
src/directives/index.js

@@ -30,7 +30,7 @@ module.exports = {
     focus: function (value) {
         var el = this.el
         setTimeout(function () {
-            el[value ? 'focus' : 'focus']()
+            if (value) el.focus()
         }, 0)
     },
 

+ 1 - 1
src/directives/on.js

@@ -64,7 +64,7 @@ module.exports = {
                 if (compiler.each) {
                     e.item = vm[compiler.eachPrefix]
                 }
-                handler.call(vm, e)
+                handler.call(ownerVM, e)
             }
             this.el.addEventListener(event, this.handler)
 

+ 14 - 4
src/exp-parser.js

@@ -1,6 +1,4 @@
-/*
- *  Variable extraction scooped from https://github.com/RubyLouvre/avalon 
- */
+// Variable extraction scooped from https://github.com/RubyLouvre/avalon 
 var KEYWORDS =
         // keywords
         'break,case,catch,continue,debugger,default,delete,do,else,false'
@@ -32,7 +30,13 @@ function getVariables (code) {
 }
 
 module.exports = {
-    parseGetter: function (exp) {
+
+    /*
+     *  Parse and create an anonymous computed property getter function
+     *  from an arbitrary expression.
+     */
+    parseGetter: function (exp, compiler) {
+        // extract variable names
         var vars = getVariables(exp)
         if (!vars.length) return null
         var args = [],
@@ -40,9 +44,15 @@ module.exports = {
             hash = {}
         while (i--) {
             v = vars[i]
+            // avoid duplicate keys
             if (hash[v]) continue
             hash[v] = 1
+            // push assignment
             args.push(v + '=this.$get("' + v + '")')
+            // need to create the binding if it does not exist yet
+            if (!compiler.bindings[v]) {
+                compiler.rootCompiler.createBinding(v)
+            }
         }
         args = 'var ' + args.join(',') + ';return ' + exp
         /* jshint evil: true */