feat(core): add support for @HostBinding and @HostListener
Example: @Directive({selector: 'my-directive'}) class MyDirective { @HostBinding("attr.my-attr") myAttr: string; @HostListener("click", ["$event.target"]) onClick(target) { this.target = target; } } Closes #3996
This commit is contained in:
parent
855cb16cc7
commit
df8e15cab7
|
@ -40,7 +40,13 @@ export {
|
||||||
PropertyMetadata,
|
PropertyMetadata,
|
||||||
Event,
|
Event,
|
||||||
EventFactory,
|
EventFactory,
|
||||||
EventMetadata
|
EventMetadata,
|
||||||
|
HostBinding,
|
||||||
|
HostBindingFactory,
|
||||||
|
HostBindingMetadata,
|
||||||
|
HostListener,
|
||||||
|
HostListenerFactory,
|
||||||
|
HostListenerMetadata
|
||||||
} from './src/core/metadata';
|
} from './src/core/metadata';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import {resolveForwardRef, Injectable} from 'angular2/di';
|
import {resolveForwardRef, Injectable} from 'angular2/di';
|
||||||
import {Type, isPresent, BaseException, stringify} from 'angular2/src/core/facade/lang';
|
import {Type, isPresent, BaseException, stringify} from 'angular2/src/core/facade/lang';
|
||||||
import {ListWrapper, StringMapWrapper} from 'angular2/src/core/facade/collection';
|
import {ListWrapper, StringMap, StringMapWrapper} from 'angular2/src/core/facade/collection';
|
||||||
import {
|
import {
|
||||||
DirectiveMetadata,
|
DirectiveMetadata,
|
||||||
ComponentMetadata,
|
ComponentMetadata,
|
||||||
PropertyMetadata,
|
PropertyMetadata,
|
||||||
EventMetadata
|
EventMetadata,
|
||||||
|
HostBindingMetadata,
|
||||||
|
HostListenerMetadata
|
||||||
} from 'angular2/metadata';
|
} from 'angular2/metadata';
|
||||||
import {reflector} from 'angular2/src/core/reflection/reflection';
|
import {reflector} from 'angular2/src/core/reflection/reflection';
|
||||||
|
|
||||||
|
@ -40,6 +42,7 @@ export class DirectiveResolver {
|
||||||
StringMap<string, any[]>): DirectiveMetadata {
|
StringMap<string, any[]>): DirectiveMetadata {
|
||||||
var properties = [];
|
var properties = [];
|
||||||
var events = [];
|
var events = [];
|
||||||
|
var host = {};
|
||||||
|
|
||||||
StringMapWrapper.forEach(propertyMetadata, (metadata: any[], propName: string) => {
|
StringMapWrapper.forEach(propertyMetadata, (metadata: any[], propName: string) => {
|
||||||
metadata.forEach(a => {
|
metadata.forEach(a => {
|
||||||
|
@ -58,23 +61,37 @@ export class DirectiveResolver {
|
||||||
events.push(propName);
|
events.push(propName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (a instanceof HostBindingMetadata) {
|
||||||
|
if (isPresent(a.hostPropertyName)) {
|
||||||
|
host[`[${a.hostPropertyName}]`] = propName;
|
||||||
|
} else {
|
||||||
|
host[`[${propName}]`] = propName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a instanceof HostListenerMetadata) {
|
||||||
|
var args = isPresent(a.args) ? a.args.join(', ') : '';
|
||||||
|
host[`(${a.eventName})`] = `${propName}(${args})`;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
return this._merge(dm, properties, events, host);
|
||||||
return this._merge(dm, properties, events);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _merge(dm: DirectiveMetadata, properties: string[], events: string[]): DirectiveMetadata {
|
private _merge(dm: DirectiveMetadata, properties: string[], events: string[],
|
||||||
|
host: StringMap<string, string>): DirectiveMetadata {
|
||||||
var mergedProperties =
|
var mergedProperties =
|
||||||
isPresent(dm.properties) ? ListWrapper.concat(dm.properties, properties) : properties;
|
isPresent(dm.properties) ? ListWrapper.concat(dm.properties, properties) : properties;
|
||||||
var mergedEvents = isPresent(dm.events) ? ListWrapper.concat(dm.events, events) : events;
|
var mergedEvents = isPresent(dm.events) ? ListWrapper.concat(dm.events, events) : events;
|
||||||
|
var mergedHost = isPresent(dm.host) ? StringMapWrapper.merge(dm.host, host) : host;
|
||||||
|
|
||||||
if (dm instanceof ComponentMetadata) {
|
if (dm instanceof ComponentMetadata) {
|
||||||
return new ComponentMetadata({
|
return new ComponentMetadata({
|
||||||
selector: dm.selector,
|
selector: dm.selector,
|
||||||
properties: mergedProperties,
|
properties: mergedProperties,
|
||||||
events: mergedEvents,
|
events: mergedEvents,
|
||||||
host: dm.host,
|
host: mergedHost,
|
||||||
lifecycle: dm.lifecycle,
|
lifecycle: dm.lifecycle,
|
||||||
bindings: dm.bindings,
|
bindings: dm.bindings,
|
||||||
exportAs: dm.exportAs,
|
exportAs: dm.exportAs,
|
||||||
|
@ -88,7 +105,7 @@ export class DirectiveResolver {
|
||||||
selector: dm.selector,
|
selector: dm.selector,
|
||||||
properties: mergedProperties,
|
properties: mergedProperties,
|
||||||
events: mergedEvents,
|
events: mergedEvents,
|
||||||
host: dm.host,
|
host: mergedHost,
|
||||||
lifecycle: dm.lifecycle,
|
lifecycle: dm.lifecycle,
|
||||||
bindings: dm.bindings,
|
bindings: dm.bindings,
|
||||||
exportAs: dm.exportAs,
|
exportAs: dm.exportAs,
|
||||||
|
|
|
@ -112,3 +112,19 @@ class Event extends EventMetadata {
|
||||||
const Event([String bindingPropertyName])
|
const Event([String bindingPropertyName])
|
||||||
: super(bindingPropertyName);
|
: super(bindingPropertyName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See: [HostBindingMetadata] for docs.
|
||||||
|
*/
|
||||||
|
class HostBinding extends HostBindingMetadata {
|
||||||
|
const HostBinding([String hostPropertyName])
|
||||||
|
: super(hostPropertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See: [HostListenerMetadata] for docs.
|
||||||
|
*/
|
||||||
|
class HostListener extends HostListenerMetadata {
|
||||||
|
const HostListener(String eventName, [List<String> args])
|
||||||
|
: super(eventName, args);
|
||||||
|
}
|
|
@ -15,7 +15,9 @@ export {
|
||||||
PipeMetadata,
|
PipeMetadata,
|
||||||
LifecycleEvent,
|
LifecycleEvent,
|
||||||
PropertyMetadata,
|
PropertyMetadata,
|
||||||
EventMetadata
|
EventMetadata,
|
||||||
|
HostBindingMetadata,
|
||||||
|
HostListenerMetadata
|
||||||
} from './metadata/directives';
|
} from './metadata/directives';
|
||||||
|
|
||||||
export {ViewMetadata, ViewEncapsulation} from './metadata/view';
|
export {ViewMetadata, ViewEncapsulation} from './metadata/view';
|
||||||
|
@ -33,7 +35,9 @@ import {
|
||||||
PipeMetadata,
|
PipeMetadata,
|
||||||
LifecycleEvent,
|
LifecycleEvent,
|
||||||
PropertyMetadata,
|
PropertyMetadata,
|
||||||
EventMetadata
|
EventMetadata,
|
||||||
|
HostBindingMetadata,
|
||||||
|
HostListenerMetadata
|
||||||
} from './metadata/directives';
|
} from './metadata/directives';
|
||||||
|
|
||||||
import {ViewMetadata, ViewEncapsulation} from './metadata/view';
|
import {ViewMetadata, ViewEncapsulation} from './metadata/view';
|
||||||
|
@ -447,6 +451,45 @@ export interface EventFactory {
|
||||||
new (bindingPropertyName?: string): any;
|
new (bindingPropertyName?: string): any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link HostBindingMetadata} factory for creating decorators.
|
||||||
|
*
|
||||||
|
* ## Example as TypeScript Decorator
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* @Directive({
|
||||||
|
* selector: 'sample-dir'
|
||||||
|
* })
|
||||||
|
* class SampleDir {
|
||||||
|
* @HostBinding() prop1; // Same as @HostBinding('prop1') prop1;
|
||||||
|
* @HostBinding("el-prop") prop1;
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export interface HostBindingFactory {
|
||||||
|
(hostPropertyName?: string): any;
|
||||||
|
new (hostPropertyName?: string): any;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link HostListenerMetadata} factory for creating decorators.
|
||||||
|
*
|
||||||
|
* ## Example as TypeScript Decorator
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* @Directive({
|
||||||
|
* selector: 'sample-dir'
|
||||||
|
* })
|
||||||
|
* class SampleDir {
|
||||||
|
* @HostListener("change", ['$event.target.value']) onChange(value){}
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export interface HostListenerFactory {
|
||||||
|
(eventName: string, args?: string[]): any;
|
||||||
|
new (eventName: string, args?: string[]): any;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ComponentMetadata} factory function.
|
* {@link ComponentMetadata} factory function.
|
||||||
*/
|
*/
|
||||||
|
@ -492,4 +535,14 @@ export var Property: PropertyFactory = makePropDecorator(PropertyMetadata);
|
||||||
/**
|
/**
|
||||||
* {@link EventMetadata} factory function.
|
* {@link EventMetadata} factory function.
|
||||||
*/
|
*/
|
||||||
export var Event: EventFactory = makePropDecorator(EventMetadata);
|
export var Event: EventFactory = makePropDecorator(EventMetadata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link HostBindingMetadata} factory function.
|
||||||
|
*/
|
||||||
|
export var HostBinding: HostBindingFactory = makePropDecorator(HostBindingMetadata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link HostListenerMetadata} factory function.
|
||||||
|
*/
|
||||||
|
export var HostListener: HostListenerFactory = makePropDecorator(HostListenerMetadata);
|
|
@ -1109,4 +1109,68 @@ export class PropertyMetadata {
|
||||||
@CONST()
|
@CONST()
|
||||||
export class EventMetadata {
|
export class EventMetadata {
|
||||||
constructor(public bindingPropertyName?: string) {}
|
constructor(public bindingPropertyName?: string) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declare a host property binding.
|
||||||
|
*
|
||||||
|
* ## Example
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* @Directive({
|
||||||
|
* selector: 'sample-dir'
|
||||||
|
* })
|
||||||
|
* class SampleDir {
|
||||||
|
* @HostBinding() prop1; // Same as @HostBinding('prop1') prop1;
|
||||||
|
* @HostBinding("el-prop") prop2;
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* This is equivalent to
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* @Directive({
|
||||||
|
* selector: 'sample-dir',
|
||||||
|
* host: {'[prop1]': 'prop1', '[el-prop]': 'prop2'}
|
||||||
|
* })
|
||||||
|
* class SampleDir {
|
||||||
|
* prop1;
|
||||||
|
* prop2;
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
@CONST()
|
||||||
|
export class HostBindingMetadata {
|
||||||
|
constructor(public hostPropertyName?: string) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declare a host listener.
|
||||||
|
*
|
||||||
|
* ## Example
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* @Directive({
|
||||||
|
* selector: 'sample-dir'
|
||||||
|
* })
|
||||||
|
* class SampleDir {
|
||||||
|
* @HostListener("change", ['$event.target.value']) onChange(value){}
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* This is equivalent to
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* @Directive({
|
||||||
|
* selector: 'sample-dir',
|
||||||
|
* host: {'(change)': 'onChange($event.target.value)'}
|
||||||
|
* })
|
||||||
|
* class SampleDir {
|
||||||
|
* onChange(value){}
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
@CONST()
|
||||||
|
export class HostListenerMetadata {
|
||||||
|
constructor(public eventName: string, public args?: string[]) {}
|
||||||
}
|
}
|
|
@ -1,6 +1,13 @@
|
||||||
import {ddescribe, describe, it, iit, expect, beforeEach} from 'angular2/test_lib';
|
import {ddescribe, describe, it, iit, expect, beforeEach} from 'angular2/test_lib';
|
||||||
import {DirectiveResolver} from 'angular2/src/core/compiler/directive_resolver';
|
import {DirectiveResolver} from 'angular2/src/core/compiler/directive_resolver';
|
||||||
import {DirectiveMetadata, Directive, Property, Event} from 'angular2/metadata';
|
import {
|
||||||
|
DirectiveMetadata,
|
||||||
|
Directive,
|
||||||
|
Property,
|
||||||
|
Event,
|
||||||
|
HostBinding,
|
||||||
|
HostListener
|
||||||
|
} from 'angular2/metadata';
|
||||||
|
|
||||||
@Directive({selector: 'someDirective'})
|
@Directive({selector: 'someDirective'})
|
||||||
class SomeDirective {
|
class SomeDirective {
|
||||||
|
@ -11,7 +18,7 @@ class SomeChildDirective extends SomeDirective {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Directive({selector: 'someDirective', properties: ['c']})
|
@Directive({selector: 'someDirective', properties: ['c']})
|
||||||
class SomeDirectiveWithProps {
|
class SomeDirectiveWithProperties {
|
||||||
@Property() a;
|
@Property() a;
|
||||||
@Property("renamed") b;
|
@Property("renamed") b;
|
||||||
c;
|
c;
|
||||||
|
@ -40,6 +47,23 @@ class SomeDirectiveWithGetterEvents {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Directive({selector: 'someDirective', host: {'[c]': 'c'}})
|
||||||
|
class SomeDirectiveWithHostBindings {
|
||||||
|
@HostBinding() a;
|
||||||
|
@HostBinding("renamed") b;
|
||||||
|
c;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Directive({selector: 'someDirective', host: {'(c)': 'onC()'}})
|
||||||
|
class SomeDirectiveWithHostListeners {
|
||||||
|
@HostListener('a')
|
||||||
|
onA() {
|
||||||
|
}
|
||||||
|
@HostListener('b', ['$event.value'])
|
||||||
|
onB(value) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class SomeDirectiveWithoutMetadata {}
|
class SomeDirectiveWithoutMetadata {}
|
||||||
|
|
||||||
|
@ -52,7 +76,8 @@ export function main() {
|
||||||
it('should read out the Directive metadata', () => {
|
it('should read out the Directive metadata', () => {
|
||||||
var directiveMetadata = resolver.resolve(SomeDirective);
|
var directiveMetadata = resolver.resolve(SomeDirective);
|
||||||
expect(directiveMetadata)
|
expect(directiveMetadata)
|
||||||
.toEqual(new DirectiveMetadata({selector: 'someDirective', properties: [], events: []}));
|
.toEqual(new DirectiveMetadata(
|
||||||
|
{selector: 'someDirective', properties: [], events: [], host: {}}));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw if not matching metadata is found', () => {
|
it('should throw if not matching metadata is found', () => {
|
||||||
|
@ -63,39 +88,44 @@ export function main() {
|
||||||
it('should not read parent class Directive metadata', function() {
|
it('should not read parent class Directive metadata', function() {
|
||||||
var directiveMetadata = resolver.resolve(SomeChildDirective);
|
var directiveMetadata = resolver.resolve(SomeChildDirective);
|
||||||
expect(directiveMetadata)
|
expect(directiveMetadata)
|
||||||
.toEqual(
|
.toEqual(new DirectiveMetadata(
|
||||||
new DirectiveMetadata({selector: 'someChildDirective', properties: [], events: []}));
|
{selector: 'someChildDirective', properties: [], events: [], host: {}}));
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('properties', () => {
|
describe('properties', () => {
|
||||||
it('should append directive properties', () => {
|
it('should append directive properties', () => {
|
||||||
var directiveMetadata = resolver.resolve(SomeDirectiveWithProps);
|
var directiveMetadata = resolver.resolve(SomeDirectiveWithProperties);
|
||||||
expect(directiveMetadata)
|
expect(directiveMetadata.properties).toEqual(['c', 'a', 'b: renamed']);
|
||||||
.toEqual(new DirectiveMetadata(
|
|
||||||
{selector: 'someDirective', properties: ['c', 'a', 'b: renamed'], events: []}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with getters and setters', () => {
|
it('should work with getters and setters', () => {
|
||||||
var directiveMetadata = resolver.resolve(SomeDirectiveWithSetterProps);
|
var directiveMetadata = resolver.resolve(SomeDirectiveWithSetterProps);
|
||||||
expect(directiveMetadata)
|
expect(directiveMetadata.properties).toEqual(['a: renamed']);
|
||||||
.toEqual(new DirectiveMetadata(
|
|
||||||
{selector: 'someDirective', properties: ['a: renamed'], events: []}));
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('events', () => {
|
describe('events', () => {
|
||||||
it('should append directive events', () => {
|
it('should append directive events', () => {
|
||||||
var directiveMetadata = resolver.resolve(SomeDirectiveWithEvents);
|
var directiveMetadata = resolver.resolve(SomeDirectiveWithEvents);
|
||||||
expect(directiveMetadata)
|
expect(directiveMetadata.events).toEqual(['c', 'a', 'b: renamed']);
|
||||||
.toEqual(new DirectiveMetadata(
|
|
||||||
{selector: 'someDirective', properties: [], events: ['c', 'a', 'b: renamed']}));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work with getters and setters', () => {
|
it('should work with getters and setters', () => {
|
||||||
var directiveMetadata = resolver.resolve(SomeDirectiveWithGetterEvents);
|
var directiveMetadata = resolver.resolve(SomeDirectiveWithGetterEvents);
|
||||||
expect(directiveMetadata)
|
expect(directiveMetadata.events).toEqual(['a: renamed']);
|
||||||
.toEqual(new DirectiveMetadata(
|
});
|
||||||
{selector: 'someDirective', properties: [], events: ['a: renamed']}));
|
});
|
||||||
|
|
||||||
|
describe('host', () => {
|
||||||
|
it('should append host bindings', () => {
|
||||||
|
var directiveMetadata = resolver.resolve(SomeDirectiveWithHostBindings);
|
||||||
|
expect(directiveMetadata.host).toEqual({'[c]': 'c', '[a]': 'a', '[renamed]': 'b'});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should append host listeners', () => {
|
||||||
|
var directiveMetadata = resolver.resolve(SomeDirectiveWithHostListeners);
|
||||||
|
expect(directiveMetadata.host)
|
||||||
|
.toEqual({'(c)': 'onC()', '(a)': 'onA()', '(b)': 'onB($event.value)'});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -73,7 +73,9 @@ import {
|
||||||
Query,
|
Query,
|
||||||
Pipe,
|
Pipe,
|
||||||
Property,
|
Property,
|
||||||
Event
|
Event,
|
||||||
|
HostBinding,
|
||||||
|
HostListener
|
||||||
} from 'angular2/metadata';
|
} from 'angular2/metadata';
|
||||||
|
|
||||||
import {QueryList} from 'angular2/src/core/compiler/query_list';
|
import {QueryList} from 'angular2/src/core/compiler/query_list';
|
||||||
|
@ -1625,6 +1627,24 @@ export function main() {
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
it('should support host binding decorators',
|
||||||
|
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||||
|
tcb.overrideView(MyComp, new ViewMetadata({
|
||||||
|
template: '<with-prop-decorators></with-prop-decorators>',
|
||||||
|
directives: [DirectiveWithPropDecorators]
|
||||||
|
}))
|
||||||
|
.createAsync(MyComp)
|
||||||
|
.then((rootTC) => {
|
||||||
|
rootTC.detectChanges();
|
||||||
|
var dir = rootTC.componentViewChildren[0].inject(DirectiveWithPropDecorators);
|
||||||
|
dir.myAttr = "aaa";
|
||||||
|
|
||||||
|
rootTC.detectChanges();
|
||||||
|
expect(DOM.getOuterHTML(rootTC.componentViewChildren[0].nativeElement))
|
||||||
|
.toContain('my-attr="aaa"');
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
|
||||||
if (DOM.supportsDOMEvents()) {
|
if (DOM.supportsDOMEvents()) {
|
||||||
it('should support events decorators',
|
it('should support events decorators',
|
||||||
|
@ -1647,6 +1667,26 @@ export function main() {
|
||||||
|
|
||||||
expect(rootTC.componentInstance.ctxProp).toEqual("called");
|
expect(rootTC.componentInstance.ctxProp).toEqual("called");
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
|
||||||
|
it('should support host listener decorators',
|
||||||
|
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder,
|
||||||
|
async) => {
|
||||||
|
tcb.overrideView(MyComp, new ViewMetadata({
|
||||||
|
template: '<with-prop-decorators></with-prop-decorators>',
|
||||||
|
directives: [DirectiveWithPropDecorators]
|
||||||
|
}))
|
||||||
|
.createAsync(MyComp)
|
||||||
|
.then((rootTC) => {
|
||||||
|
rootTC.detectChanges();
|
||||||
|
var dir = rootTC.componentViewChildren[0].inject(DirectiveWithPropDecorators);
|
||||||
|
var native = rootTC.componentViewChildren[0].nativeElement;
|
||||||
|
native.click();
|
||||||
|
|
||||||
|
expect(dir.target).toBe(native);
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -2203,8 +2243,16 @@ class DirectiveThrowingAnError {
|
||||||
|
|
||||||
@Directive({selector: 'with-prop-decorators'})
|
@Directive({selector: 'with-prop-decorators'})
|
||||||
class DirectiveWithPropDecorators {
|
class DirectiveWithPropDecorators {
|
||||||
|
target;
|
||||||
|
|
||||||
@Property("elProp") dirProp: string;
|
@Property("elProp") dirProp: string;
|
||||||
@Event('elEvent') event = new EventEmitter();
|
@Event('elEvent') event = new EventEmitter();
|
||||||
|
|
||||||
|
@HostBinding("attr.my-attr") myAttr: string;
|
||||||
|
@HostListener("click", ["$event.target"])
|
||||||
|
onClick(target) {
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
fireEvent(msg) { ObservableWrapper.callNext(this.event, msg); }
|
fireEvent(msg) { ObservableWrapper.callNext(this.event, msg); }
|
||||||
}
|
}
|
Loading…
Reference in New Issue