diff --git a/compiler/generate/index.js b/compiler/generate/index.js index 5e405566f2..22b37ee52c 100644 --- a/compiler/generate/index.js +++ b/compiler/generate/index.js @@ -235,17 +235,29 @@ export default function generate ( parsed, template ) { } else if ( attribute.type === 'Binding' ) { - if ( attribute.value in current.contexts ) { - throw new Error( `Can only bind top-level properties` ); - } + const parts = attribute.value.split( '.' ); + const contextual = parts[0] in current.contexts; const handler = current.counter( `${name}ChangeHandler` ); + let setter; + + if ( contextual ) { + allUsedContexts.add( parts[0] ); + setter = deindent` + var context = this.__context.${parts[0]}; + context.${parts.slice( 1 ).join( '.' )} = this.value; + component.set({ ${current.contextChain[0]}: component.get( '${current.contextChain[0]}' ) }); + `; + } else { + setter = `component.set({ ${attribute.value}: ${name}.value });`; + } initStatements.push( deindent` var ${name}_updating = false; + function ${handler} () { ${name}_updating = true; - component.set({ ${attribute.value}: ${name}.value }); + ${setter} ${name}_updating = false; } @@ -253,7 +265,7 @@ export default function generate ( parsed, template ) { ` ); updateStatements.push( deindent` - if ( !${name}_updating ) ${name}.value = root.${attribute.value}; + if ( !${name}_updating ) ${name}.value = ${contextual ? attribute.value : `root.${attribute.value}`} ` ); teardownStatements.push( deindent` diff --git a/compiler/parse/read/directives.js b/compiler/parse/read/directives.js index 3573a5ded3..e1bd3f6c30 100644 --- a/compiler/parse/read/directives.js +++ b/compiler/parse/read/directives.js @@ -49,7 +49,7 @@ export function readBindingDirective ( parser, start, name ) { null ); - const value = parser.read( /[a-zA-Z_$][a-zA-Z0-9_$]*/ ); // TODO – keypaths? /([a-zA-Z_$][a-zA-Z0-9_$]*)(\.[a-zA-Z_$][a-zA-Z0-9_$]*)*/ + const value = parser.read( /([a-zA-Z_$][a-zA-Z0-9_$]*)(\.[a-zA-Z_$][a-zA-Z0-9_$]*)*/ ); if ( !value ) parser.error( `Expected valid property name` ); if ( quoteMark ) { diff --git a/test/compiler/binding-input-text-deep/_config.js b/test/compiler/binding-input-text-deep/_config.js new file mode 100644 index 0000000000..ada981c7a5 --- /dev/null +++ b/test/compiler/binding-input-text-deep/_config.js @@ -0,0 +1,31 @@ +import * as assert from 'assert'; + +export default { + data: { + items: [ + { description: 'one' }, + { description: 'two' }, + { description: 'three' } + ] + }, + html: `
one
two
three
one
four
three
one
four
five
{{item.description}}