feat(compiler): added support for [()] syntax
This commit is contained in:
parent
846354473d
commit
685a6507b6
|
@ -151,7 +151,7 @@ export class AppView {
|
||||||
}
|
}
|
||||||
var result = expr.eval(context, new Locals(this.locals, locals));
|
var result = expr.eval(context, new Locals(this.locals, locals));
|
||||||
if (isPresent(result)) {
|
if (isPresent(result)) {
|
||||||
allowDefaultBehavior = allowDefaultBehavior && result;
|
allowDefaultBehavior = allowDefaultBehavior && result == true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,12 +12,13 @@ import {dashCaseToCamelCase} from '../util';
|
||||||
// Group 1 = "bind-"
|
// Group 1 = "bind-"
|
||||||
// Group 2 = "var-" or "#"
|
// Group 2 = "var-" or "#"
|
||||||
// Group 3 = "on-"
|
// Group 3 = "on-"
|
||||||
// Group 4 = the identifier after "bind-", "var-/#", or "on-"
|
// Group 4 = "bindon-"
|
||||||
// Group 5 = idenitifer inside square braces
|
// Group 5 = the identifier after "bind-", "var-/#", or "on-"
|
||||||
// Group 6 = identifier inside parenthesis
|
// Group 6 = idenitifer inside [()]
|
||||||
|
// Group 7 = idenitifer inside []
|
||||||
|
// Group 8 = identifier inside ()
|
||||||
var BIND_NAME_REGEXP = RegExpWrapper.create(
|
var BIND_NAME_REGEXP = RegExpWrapper.create(
|
||||||
'^(?:(?:(?:(bind-)|(var-|#)|(on-))(.+))|\\[([^\\]]+)\\]|\\(([^\\)]+)\\))$');
|
'^(?:(?:(?:(bind-)|(var-|#)|(on-)|(bindon-))(.+))|\\[\\(([^\\)]+)\\)\\]|\\[([^\\]]+)\\]|\\(([^\\)]+)\\))$');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the property bindings on a single element.
|
* Parses the property bindings on a single element.
|
||||||
*/
|
*/
|
||||||
|
@ -36,23 +37,30 @@ export class PropertyBindingParser extends CompileStep {
|
||||||
MapWrapper.forEach(attrs, (attrValue, attrName) => {
|
MapWrapper.forEach(attrs, (attrValue, attrName) => {
|
||||||
var bindParts = RegExpWrapper.firstMatch(BIND_NAME_REGEXP, attrName);
|
var bindParts = RegExpWrapper.firstMatch(BIND_NAME_REGEXP, attrName);
|
||||||
if (isPresent(bindParts)) {
|
if (isPresent(bindParts)) {
|
||||||
if (isPresent(bindParts[1])) {
|
if (isPresent(bindParts[1])) { // match: bind-prop
|
||||||
// match: bind-prop
|
this._bindProperty(bindParts[5], attrValue, current, newAttrs);
|
||||||
this._bindProperty(bindParts[4], attrValue, current, newAttrs);
|
|
||||||
} else if (isPresent(bindParts[2])) {
|
} else if (isPresent(bindParts[2])) { // match: var-name / var-name="iden" / #name / #name="iden"
|
||||||
// match: var-name / var-name="iden" / #name / #name="iden"
|
var identifier = bindParts[5];
|
||||||
var identifier = bindParts[4];
|
|
||||||
var value = attrValue == '' ? '\$implicit' : attrValue;
|
var value = attrValue == '' ? '\$implicit' : attrValue;
|
||||||
this._bindVariable(identifier, value, current, newAttrs);
|
this._bindVariable(identifier, value, current, newAttrs);
|
||||||
} else if (isPresent(bindParts[3])) {
|
|
||||||
// match: on-event
|
} else if (isPresent(bindParts[3])) { // match: on-event
|
||||||
this._bindEvent(bindParts[4], attrValue, current, newAttrs);
|
this._bindEvent(bindParts[5], attrValue, current, newAttrs);
|
||||||
} else if (isPresent(bindParts[5])) {
|
|
||||||
// match: [prop]
|
} else if (isPresent(bindParts[4])) { // match: bindon-prop
|
||||||
this._bindProperty(bindParts[5], attrValue, current, newAttrs);
|
this._bindProperty(bindParts[5], attrValue, current, newAttrs);
|
||||||
} else if (isPresent(bindParts[6])) {
|
this._bindAssignmentEvent(bindParts[5], attrValue, current, newAttrs);
|
||||||
// match: (event)
|
|
||||||
this._bindEvent(bindParts[6], attrValue, current, newAttrs);
|
} else if (isPresent(bindParts[6])) { // match: [(expr)]
|
||||||
|
this._bindProperty(bindParts[6], attrValue, current, newAttrs);
|
||||||
|
this._bindAssignmentEvent(bindParts[6], attrValue, current, newAttrs);
|
||||||
|
|
||||||
|
} else if (isPresent(bindParts[7])) { // match: [expr]
|
||||||
|
this._bindProperty(bindParts[7], attrValue, current, newAttrs);
|
||||||
|
|
||||||
|
} else if (isPresent(bindParts[8])) { // match: (event)
|
||||||
|
this._bindEvent(bindParts[8], attrValue, current, newAttrs);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var expr = this._parser.parseInterpolation(
|
var expr = this._parser.parseInterpolation(
|
||||||
|
@ -90,6 +98,10 @@ export class PropertyBindingParser extends CompileStep {
|
||||||
MapWrapper.set(newAttrs, name, ast.source);
|
MapWrapper.set(newAttrs, name, ast.source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_bindAssignmentEvent(name, expression, current:CompileElement, newAttrs) {
|
||||||
|
this._bindEvent(name, `${expression}=$event`, current, newAttrs);
|
||||||
|
}
|
||||||
|
|
||||||
_bindEvent(name, expression, current:CompileElement, newAttrs) {
|
_bindEvent(name, expression, current:CompileElement, newAttrs) {
|
||||||
current.bindElement().bindEvent(
|
current.bindElement().bindEvent(
|
||||||
dashCaseToCamelCase(name), this._parser.parseAction(expression, current.elementDescription)
|
dashCaseToCamelCase(name), this._parser.parseAction(expression, current.elementDescription)
|
||||||
|
|
|
@ -603,6 +603,30 @@ export function main() {
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should support [()] syntax', inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||||
|
tb.overrideView(MyComp, new View({
|
||||||
|
template: '<div [(control)]="ctxProp" two-way></div>',
|
||||||
|
directives: [DirectiveWithTwoWayBinding]
|
||||||
|
}));
|
||||||
|
|
||||||
|
tb.createView(MyComp, {context: ctx}).then((view) => {
|
||||||
|
var injector = view.rawView.elementInjectors[0];
|
||||||
|
var dir = injector.get(DirectiveWithTwoWayBinding);
|
||||||
|
|
||||||
|
ctx.ctxProp = 'one';
|
||||||
|
view.detectChanges();
|
||||||
|
|
||||||
|
expect(dir.value).toEqual('one');
|
||||||
|
|
||||||
|
ObservableWrapper.subscribe(dir.control, (_) => {
|
||||||
|
expect(ctx.ctxProp).toEqual('two');
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
|
||||||
|
dir.triggerChange('two');
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
if (DOM.supportsDOMEvents()) {
|
if (DOM.supportsDOMEvents()) {
|
||||||
it("should support invoking methods on the host element via hostActions", inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
it("should support invoking methods on the host element via hostActions", inject([TestBed, AsyncTestCompleter], (tb, async) => {
|
||||||
tb.overrideView(MyComp, new View({
|
tb.overrideView(MyComp, new View({
|
||||||
|
@ -1529,3 +1553,21 @@ class ToolbarComponent {
|
||||||
this.query = query;
|
this.query = query;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: '[two-way]',
|
||||||
|
properties: {value: 'control'},
|
||||||
|
events: ['control']
|
||||||
|
})
|
||||||
|
class DirectiveWithTwoWayBinding {
|
||||||
|
control:EventEmitter;
|
||||||
|
value:any;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.control = new EventEmitter();
|
||||||
|
}
|
||||||
|
|
||||||
|
triggerChange(value) {
|
||||||
|
ObservableWrapper.callNext(this.control, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -149,6 +149,18 @@ export function main() {
|
||||||
expect(MapWrapper.get(results[0].attrs(), 'a')).toEqual('b');
|
expect(MapWrapper.get(results[0].attrs(), 'a')).toEqual('b');
|
||||||
expect(MapWrapper.get(results[0].attrs(), 'c')).toEqual('d');
|
expect(MapWrapper.get(results[0].attrs(), 'c')).toEqual('d');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should detect [()] syntax', () => {
|
||||||
|
var results = process(el('<div [(a)]="b"></div>'));
|
||||||
|
expect(MapWrapper.get(results[0].propertyBindings, 'a').source).toEqual('b');
|
||||||
|
expect(results[0].eventBindings[0].source.source).toEqual('b=$event');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should detect bindon- syntax', () => {
|
||||||
|
var results = process(el('<div bindon-a="b"></div>'));
|
||||||
|
expect(MapWrapper.get(results[0].propertyBindings, 'a').source).toEqual('b');
|
||||||
|
expect(results[0].eventBindings[0].source.source).toEqual('b=$event');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue