feat(compiler): make directive bindings optional. Fixes #647

This commit is contained in:
Jeremy Elbourn 2015-02-18 10:54:28 -08:00
parent 74c0699ad9
commit 785ec26322
3 changed files with 39 additions and 19 deletions

View File

@ -204,15 +204,16 @@ export class ElementBinderBuilder extends CompileStep {
var attributeValue = MapWrapper.get(compileElement.attrs(), elProp); var attributeValue = MapWrapper.get(compileElement.attrs(), elProp);
if (isPresent(attributeValue)) { if (isPresent(attributeValue)) {
expression = _this._parser.wrapLiteralPrimitive(attributeValue, _this._compilationUnit); expression = _this._parser.wrapLiteralPrimitive(attributeValue, _this._compilationUnit);
} else {
throw new BaseException("No element binding found for property '" + elProp
+ "' which is required by directive '" + stringify(directive.type) + "'");
} }
} }
// Bindings are optional, so this binding only needs to be set up if an expression is given.
if (isPresent(expression)) {
var len = dirProp.length; var len = dirProp.length;
var dirBindingName = dirProp; var dirBindingName = dirProp;
var isContentWatch = dirProp[len - 2] === '[' && dirProp[len - 1] === ']'; var isContentWatch = dirProp[len - 2] === '[' && dirProp[len - 1] === ']';
if (isContentWatch) dirBindingName = dirProp.substring(0, len - 2); if (isContentWatch) dirBindingName = dirProp.substring(0, len - 2);
protoView.bindDirectiveProperty( protoView.bindDirectiveProperty(
directiveIndex, directiveIndex,
expression, expression,
@ -220,6 +221,7 @@ export class ElementBinderBuilder extends CompileStep {
reflector.setter(dirBindingName), reflector.setter(dirBindingName),
isContentWatch isContentWatch
); );
}
}); });
} }
} }

View File

@ -151,6 +151,20 @@ export function main() {
}); });
}); });
it('should support directives where a binding attribute is not given', function(done) {
tplResolver.setTemplate(MyComp,
new Template({
// No attribute "el-prop" specified.
inline: '<p my-dir></p>',
directives: [MyDir]
}));
compiler.compile(MyComp).then((pv) => {
createView(pv);
done();
});
});
it('should support template directives via `<template>` elements.', (done) => { it('should support template directives via `<template>` elements.', (done) => {
tplResolver.setTemplate(MyComp, tplResolver.setTemplate(MyComp,
new Template({ new Template({

View File

@ -430,11 +430,15 @@ export function main() {
describe('errors', () => { describe('errors', () => {
it('should throw if there is no element property bindings for a directive property binding', () => { it('should not throw any errors if there is no element property bindings for a directive ' +
var pipeline = createPipeline({propertyBindings: MapWrapper.create(), directives: [SomeDecoratorDirectiveWithBinding]}); 'property binding', () => {
expect( () => { var pipeline = createPipeline({
propertyBindings: MapWrapper.create(),
directives: [SomeDecoratorDirectiveWithBinding]
});
// If processing throws an error, this test will fail.
pipeline.process(el('<div viewroot prop-binding directives>')); pipeline.process(el('<div viewroot prop-binding directives>'));
}).toThrowError("No element binding found for property 'boundprop1' which is required by directive 'SomeDecoratorDirectiveWithBinding'");
}); });
}); });