jps*_*sfs 15 typescript angular
我正在使用Angular 2进行一些测试,我有一个可以应用于我所有组件的指令(layout-item).
在该指令中,我希望能够读取组件上定义的一些元数据,但为此我需要访问组件的引用.
我尝试了以下方法,但我无法得到我需要的东西.有人有建议吗?
@Component({...})
@View({...})
@MyAnnotation({...})
export class MyComponentA {...}
// Somewhere in a template
<myComponentA layout-item="my config 1"></myComponentA>
<myComponentB layout-item="my config 2"></myComponentA>
// ----------------------
@ng.Directive({
selector: "[layout-item]",
properties: [
"strOptions: layout-item"
],
host: {
}
})
export class LayoutItem {
// What works
constructor(@Optional() @Ancestor({self: true}) private component: MyComponent1) {
// with the constructor defined like this, component is defined with myComponent1 instance.
Reflector.getMetadata("MyAnnotation", component.constructor); // > metadata is here!
}
// What I needed
constructor(@Optional() @Ancestor({self: true}) private component: any) {
// This will crash the app. If instead of any I specify some other type, the app will not crash but component will be null.
// This directive can be applied to any component, so specifying a type is not a solution.
}
}
Run Code Online (Sandbox Code Playgroud)
更新:
自Beta 16以来,没有官方的方法来获得相同的行为.这里有一个非官方的解决方法:https://github.com/angular/angular/issues/8277#issuecomment-216206046
谢谢@Eric Martinez,你的指针对于让我走向正确的方向至关重要!
所以,采取Eric的方法,我设法做了以下事情:
HTML
<my-component layout-item="my first component config"></my-component>
<my-second-component layout-item="my second component config"></my-second-component>
<my-third-component layout-item="my third component config"></my-third-component>
Run Code Online (Sandbox Code Playgroud)
三个不同的组件,所有的共享相同 layout-item属性.
指示
@Directive({
selector : '[layout-item]'
})
export class MyDirective {
constructor(private _element: ElementRef, private _viewManager: AppViewManager) {
let hostComponent = this._viewManager.getComponent(this._element);
// on hostComponent we have our component! (my-component, my-second-component, my-third-component, ... and so on!
}
}
Run Code Online (Sandbox Code Playgroud)
忘记服务,有一个更简单的形式
选项1 (不是您需要的,但对其他用户可能有用)
HTML
<my-component layout-item="my first component config"></my-component>
<my-second-component layout-item="my second component config"></my-second-component>
<my-third-component layout-item="my third component config"></my-third-component>
Run Code Online (Sandbox Code Playgroud)
三个不同的组件,所有共享相同的layout-item属性.
指示
@Directive({
selector : '[layout-item]',
properties: ['myParentConfig: my-parent-config'] // See the components for this property
})
export class MyDirective {
constructor() {
}
onInit() {
console.log(this.myParentConfig);
}
}
Run Code Online (Sandbox Code Playgroud)
很简单,这里解释不多
零件
@Component({
selector : 'my-component',
properties : ['myConfig: layout-item']
})
@View({
template : `<div [my-parent-config]="myConfig" layout-item="my config"></div>`,
directives : [MyDirective]
})
export class MyComponent {
constructor() {
}
}
Run Code Online (Sandbox Code Playgroud)
我很确定你理解这一点,但为了得到一个好的答案,我会解释它的作用
properties : ['myConfig: layout-item']`
Run Code Online (Sandbox Code Playgroud)
此行将layout-item属性分配给内部myConfig属性.
组件的模板
template : `<div [my-parent-config]="myConfig" layout-item="my config"></div>`,
Run Code Online (Sandbox Code Playgroud)
我们正在my-parent-config为指令创建一个属性,并将父级的配置分配给它.
就如此容易!所以现在我们可以使用(几乎)相同的代码添加更多组件
第二部分
@Component({
selector : 'my-second-component',
properties : ['myConfig: layout-item']
})
@View({
template : `<div [my-parent-config]="myConfig" layout-item="my config"></div>`,
directives : [MyDirective]
})
export class MySecondComponent {
constructor() {
}
}
Run Code Online (Sandbox Code Playgroud)
看到?比我使用服务的想法容易得多(糟糕但"有效"的想法).
通过这种方式,它更简单,更清洁.这是plnkr所以你可以测试它.
(这不是你需要的:'()
UPDATE
选项2
因为我对你更新的问题的理解是你需要对组件的引用,所以我提出的与我原来的答案非常相似
我做了什么 :
<my-cmp-a #pa [ref]="pa" layout-item="my first component config"></my-cmp-a>
<my-cmp-b #pb [ref]="pb" layout-item="my first component config"></my-cmp-b>
<my-cmp-c #pc [ref]="pc" layout-item="my first component config"></my-cmp-c>
Run Code Online (Sandbox Code Playgroud)
LayoutItem指令(在每个组件中注入,而不是在顶层)@Component({
selector : 'my-cmp-a',
properties : ['ref: ref']
})
@View({
template : '<div [parent-reference]="ref" layout-item=""></div>',
directives : [LayoutItem]
})
@YourCustomAnnotation({})
export class MyCmpA {
constructor() {
}
}
Run Code Online (Sandbox Code Playgroud)
@Directive({
selector : '[layout-item]',
properties : ['reference: parent-reference']
})
export class LayoutItem {
constructor() {
}
onInit() {
console.log(this.reference.constructor);
Reflector.getMetadata("YourCustomAnnotation", this.reference.constructor);
}
}
Run Code Online (Sandbox Code Playgroud)
使用此plnkr进行测试.
| 归档时间: |
|
| 查看次数: |
22076 次 |
| 最近记录: |