Skip to content

Commit 785ec26

Browse files
committed
feat(compiler): make directive bindings optional. Fixes angular#647
1 parent 74c0699 commit 785ec26

File tree

3 files changed

+39
-19
lines changed

3 files changed

+39
-19
lines changed

modules/angular2/src/core/compiler/pipeline/element_binder_builder.js

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -204,22 +204,24 @@ export class ElementBinderBuilder extends CompileStep {
204204
var attributeValue = MapWrapper.get(compileElement.attrs(), elProp);
205205
if (isPresent(attributeValue)) {
206206
expression = _this._parser.wrapLiteralPrimitive(attributeValue, _this._compilationUnit);
207-
} else {
208-
throw new BaseException("No element binding found for property '" + elProp
209-
+ "' which is required by directive '" + stringify(directive.type) + "'");
210207
}
211208
}
212-
var len = dirProp.length;
213-
var dirBindingName = dirProp;
214-
var isContentWatch = dirProp[len - 2] === '[' && dirProp[len - 1] === ']';
215-
if (isContentWatch) dirBindingName = dirProp.substring(0, len - 2);
216-
protoView.bindDirectiveProperty(
217-
directiveIndex,
218-
expression,
219-
dirBindingName,
220-
reflector.setter(dirBindingName),
221-
isContentWatch
222-
);
209+
210+
// Bindings are optional, so this binding only needs to be set up if an expression is given.
211+
if (isPresent(expression)) {
212+
var len = dirProp.length;
213+
var dirBindingName = dirProp;
214+
var isContentWatch = dirProp[len - 2] === '[' && dirProp[len - 1] === ']';
215+
if (isContentWatch) dirBindingName = dirProp.substring(0, len - 2);
216+
217+
protoView.bindDirectiveProperty(
218+
directiveIndex,
219+
expression,
220+
dirBindingName,
221+
reflector.setter(dirBindingName),
222+
isContentWatch
223+
);
224+
}
223225
});
224226
}
225227
}

modules/angular2/test/core/compiler/integration_spec.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,20 @@ export function main() {
151151
});
152152
});
153153

154+
it('should support directives where a binding attribute is not given', function(done) {
155+
tplResolver.setTemplate(MyComp,
156+
new Template({
157+
// No attribute "el-prop" specified.
158+
inline: '<p my-dir></p>',
159+
directives: [MyDir]
160+
}));
161+
162+
compiler.compile(MyComp).then((pv) => {
163+
createView(pv);
164+
done();
165+
});
166+
});
167+
154168
it('should support template directives via `<template>` elements.', (done) => {
155169
tplResolver.setTemplate(MyComp,
156170
new Template({

modules/angular2/test/core/compiler/pipeline/element_binder_builder_spec.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -430,11 +430,15 @@ export function main() {
430430

431431
describe('errors', () => {
432432

433-
it('should throw if there is no element property bindings for a directive property binding', () => {
434-
var pipeline = createPipeline({propertyBindings: MapWrapper.create(), directives: [SomeDecoratorDirectiveWithBinding]});
435-
expect( () => {
436-
pipeline.process(el('<div viewroot prop-binding directives>'));
437-
}).toThrowError("No element binding found for property 'boundprop1' which is required by directive 'SomeDecoratorDirectiveWithBinding'");
433+
it('should not throw any errors if there is no element property bindings for a directive ' +
434+
'property binding', () => {
435+
var pipeline = createPipeline({
436+
propertyBindings: MapWrapper.create(),
437+
directives: [SomeDecoratorDirectiveWithBinding]
438+
});
439+
440+
// If processing throws an error, this test will fail.
441+
pipeline.process(el('<div viewroot prop-binding directives>'));
438442
});
439443

440444
});

0 commit comments

Comments
 (0)