better dep parsing

This commit is contained in:
Evan You 2013-08-06 13:28:34 -04:00
parent 343ea299d0
commit c4f31a5d65
4 changed files with 71 additions and 48 deletions

View File

@ -1,9 +1,5 @@
- complete arrayWatcher
- computed properties (through invoking functions, need to rework the setter triggering mechanism using emitter)
- the data object passed in should become an absolute source of truth, so multiple controllers can bind to the same data (i.e. second seed using it should insert dependency instead of overwriting it)
- nested properties in scope (kinda hard but try)
- parse textNodes

View File

@ -62,7 +62,7 @@
{ text: 'parse textnodes', done: false }
]
Seed.controller('Todos', function (scope, seed) {
Seed.controller('Todos', function (scope) {
// regular properties
scope.todos = todos
@ -82,13 +82,10 @@
// event handlers
scope.addTodo = function (e) {
var text = e.el.value
if (text) {
var val = e.el.value
if (val) {
e.el.value = ''
scope.todos.push({
text: text,
done: false
})
scope.todos.unshift({ text: val, done: false })
scope.remaining++
}
}

View File

@ -8,6 +8,46 @@ var KEY_RE = /^[^\|<]+/,
FILTER_TOKEN_RE = /[^\s']+|'[^']+'/g,
DEPS_RE = /<[^<\|]+/g
// parse a key, extract argument and nesting/root info
function parseKey (rawKey) {
var res = {},
argMatch = rawKey.match(ARG_RE)
res.key = argMatch
? argMatch[2].trim()
: rawKey.trim()
res.arg = argMatch
? argMatch[1].trim()
: null
var nesting = res.key.match(/^\^+/)
res.nesting = nesting
? nesting[0].length
: false
res.root = res.key.charAt(0) === '$'
return res
}
function parseFilter (filter) {
var tokens = filter.slice(1)
.match(FILTER_TOKEN_RE)
.map(function (token) {
return token.replace(/'/g, '').trim()
})
return {
name : tokens[0],
apply : filters[tokens[0]],
args : tokens.length > 1
? tokens.slice(1)
: null
}
}
function Directive (directiveName, expression) {
var directive = directives[directiveName]
@ -26,41 +66,22 @@ function Directive (directiveName, expression) {
this.directiveName = directiveName
this.expression = expression
var rawKey = expression.match(KEY_RE)[0], // guarded in parse
argMatch = rawKey.match(ARG_RE)
var rawKey = expression.match(KEY_RE)[0],
keyInfo = parseKey(rawKey)
this.key = argMatch
? argMatch[2].trim()
: rawKey.trim()
this.arg = argMatch
? argMatch[1].trim()
: null
for (var prop in keyInfo) {
this[prop] = keyInfo[prop]
}
var filterExps = expression.match(FILTERS_RE)
if (filterExps) {
this.filters = filterExps.map(function (filter) {
var tokens = filter.slice(1)
.match(FILTER_TOKEN_RE)
.map(function (token) {
return token.replace(/'/g, '').trim()
})
return {
name : tokens[0],
apply : filters[tokens[0]],
args : tokens.length > 1
? tokens.slice(1)
: null
}
})
} else {
this.filters = null
}
this.filters = filterExps
? filterExps.map(parseFilter)
: null
var depExp = expression.match(DEPS_RE)
if (depExp) {
this.deps = depExp[0].slice(1).trim().split(/\s+/)
}
this.deps = depExp
? depExp[0].slice(1).trim().split(/\s+/).map(parseKey)
: null
}
Directive.prototype.update = function (value) {

View File

@ -25,17 +25,19 @@ function Seed (el, options) {
// initialize the scope object
var dataPrefix = config.prefix + '-data'
this.scope =
var scope = this.scope =
(options && options.data)
|| config.datum[el.getAttribute(dataPrefix)]
|| {}
el.removeAttribute(dataPrefix)
this.scope.$seed = this
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
scope.$seed = this
scope.$destroy = this._destroy.bind(this)
scope.$dump = this._dump.bind(this)
scope.$on = this.on.bind(this)
scope.$emit = this.emit.bind(this)
scope.$index = options.index
scope.$parent = options.parentSeed && options.parentSeed.scope
// revursively process nodes for directives
this._compileNode(el, true)
@ -46,7 +48,7 @@ function Seed (el, options) {
el.removeAttribute(ctrlAttr)
var controller = config.controllers[ctrlID]
if (controller) {
controller.call(this, this.scope, this)
controller.call(this, this.scope)
} else {
console.warn('controller ' + ctrlID + ' is not defined.')
}
@ -151,6 +153,13 @@ Seed.prototype._bind = function (node, directive) {
directive.key = key
// computed properties
if (directive.deps) {
directive.deps.forEach(function (dep) {
console.log(dep)
})
}
var binding = scopeOwner._bindings[key] || scopeOwner._createBinding(key)
// add directive to this binding