fix(core): fix property decorators

fixes #12224
This commit is contained in:
Victor Berchet 2016-10-11 19:40:00 -07:00 committed by Igor Minar
parent bf1e2613b2
commit 3993279527
2 changed files with 26 additions and 7 deletions

View File

@ -354,6 +354,7 @@ export function makeParamDecorator(
export function makePropDecorator(
name: string, props: ([string, any] | {[key: string]: any})[], parentClass?: any): any {
const metaCtor = makeMetadataCtor(props);
function PropDecoratorFactory(...args: any[]): any {
if (this instanceof PropDecoratorFactory) {
metaCtor.apply(this, args);
@ -361,16 +362,19 @@ export function makePropDecorator(
}
const decoratorInstance = new (<any>PropDecoratorFactory)(...args);
return function PropDecorator(target: any, name: string) {
const meta = Reflect.getOwnMetadata('propMetadata', target.constructor) || {};
meta[name] = meta[name] || [];
meta[name] = meta.hasOwnProperty(name) && meta[name] || [];
meta[name].unshift(decoratorInstance);
Reflect.defineMetadata('propMetadata', meta, target.constructor);
};
}
if (parentClass) {
PropDecoratorFactory.prototype = Object.create(parentClass.prototype);
}
PropDecoratorFactory.prototype.toString = () => `@${name}`;
(<any>PropDecoratorFactory).annotationCls = PropDecoratorFactory;
return PropDecoratorFactory;

View File

@ -8,8 +8,7 @@
import {Inject} from '@angular/core';
import {reflector} from '@angular/core/src/reflection/reflection';
import {Class, makeDecorator} from '@angular/core/src/util/decorators';
import {describe, expect, it} from '@angular/core/testing/testing_internal';
import {Class, makeDecorator, makePropDecorator} from '@angular/core/src/util/decorators';
import {global} from '../../src/facade/lang';
@ -23,6 +22,21 @@ export function main() {
const TestDecorator = makeDecorator(
'TestDecorator', {marker: undefined}, Object, (fn: any) => fn.Terminal = TerminalDecorator);
describe('Property decorators', () => {
// https://github.com/angular/angular/issues/12224
it('should work on the "watch" property', () => {
const Prop = makePropDecorator('Prop', [['value', undefined]]);
class TestClass {
@Prop('firefox!')
watch: any;
}
const p = reflector.propMetadata(TestClass);
expect(p['watch']).toEqual([new Prop('firefox!')]);
});
});
describe('decorators', () => {
it('should invoke as decorator', () => {
function Type() {}
@ -64,10 +78,11 @@ export function main() {
constructor: function() {},
extendWorks: function() { return 'extend ' + this.arg; }
}),
constructor: [String, function(arg: any /** TODO #9100 */) { this.arg = arg; }],
constructor: [String, function(arg: any) { this.arg = arg; }],
methodA: [
i0 = new Inject(String), [i1 = Inject(String), Number],
function(a: any /** TODO #9100 */, b: any /** TODO #9100 */) {}
i0 = new Inject(String),
[i1 = Inject(String), Number],
function(a: any, b: any) {},
],
works: function() { return this.arg; },
prototype: 'IGNORE'