【问题标题】:Access controller component function from a Directive component从指令组件访问控制器组件功能
【发布时间】:2016-02-13 11:49:19
【问题描述】:

我正在尝试在 Angular 2 中创建一个简单的指令,以便可以在我的页面上使用 jQuery UI Sortables。

目前,我想让可排序的directive 知道它应该在页面Component 上调用什么函数。我想要这个,因为您可以在可排序插件中注册事件的函数。我希望指令在页面的组件上调用该函数。

我目前有这个:

@Directive({
    selector: '[sortable]'
})
export class SortableDirective {

    stopSortingEvent: any;

    constructor(el: ElementRef) {
        this.stopSortingEvent = el.nativeElement.getAttribute('stopSortingEvent');

        if(this.stopSortingEvent) {
          options['stop'] = this.stopSortingEvent; // This should be a reference to a function in the page Component.
        }

        $(el.nativeElement).sortable(options).disableSelection();
    }
}

所以我的想法是创建一个带有sorting 属性的HTML 元素。包括带有stop-sorting-event="functionOnComponent()" 的属性。

这应该是当前页面组件上的一个函数。但显然这不是这样工作的。我的指令不知道它必须尝试在另一个组件上调用它。

那么我该怎么做呢?有没有办法获得对我的页面组件的引用?


更新

我认为像素位的建议很棒,使用带有@Output 注释的事件。但是,让它与 jQueryUI 结合使用似乎很棘手。 jQueryUI 似乎无法读取我的指令的属性。

这是一个演示,可以更好地理解我的意思:http://plnkr.co/edit/Hfc5vxuMLW6yQwr4qW2W?p=preview

【问题讨论】:

    标签: angular angular2-directives


    【解决方案1】:

    如果要处理父组件中的事件,可以设置父组件可以处理的Output事件:

    @Directive({
        selector: '[sortable]'
    })
    export class SortableDirective {
        @Output() stopSort:EventEmitter<any> = new EventEmitter();
    
        constructor(el: ElementRef) {
            var options = { 
               stop: () => {
                  this.stopSort.emit();
               }
            };
    
            $(el.nativeElement).sortable(options).disableSelection();
        }
    }
    

    然后在你的父组件中:

    <div (stopSort)="stopSortingEvent()" sortable>(...)</div>
    

    【讨论】:

    【解决方案2】:

    实际上,你可以从构造函数中注入指令所附加的组件,并将函数的名称作为参数传递:

    @Directive({
      selector: '[sortable]'
    })
    export class SortableDirective {
      @Input('sortable')
      stopSortingEvent:string;
    
      constructor(el: ElementRef, page: PageComponent) {
        if(this.stopSortingEvent) {
          options['stop'] = page[stopSortingEvent].bind(page);
        }
    
        $(el.nativeElement).sortable(options).disableSelection();
      }
    

    然后您可以像这样传递方法名称:

    <div sortable="stopSortingEvent">(...)</div>
    

    【讨论】:

    • 为了完成这项工作,我需要做些什么特别的事情吗?现在我在控制台中遇到很多错误:无法解析所有参数,它说PageComponent(这是我的组件的命名方式)是未定义的。试图用@Injectable 装饰我的PageComponent 并将其添加到指令构造参数中:@Inject(PageComponent) page: PageComponent,但这也不起作用。
    • 其实需要注意循环依赖(组件->指令和指令->组件)。也许定义两个相同的模块可以解决您的问题...
    • 和 forwardRef(参见 angular.io/docs/ts/latest/api/core/forwardRef-function.html),因为类不支持提升。如果您想使用/引用稍后在模块文件中定义的类型,这适用...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-29
    相关资源
    最近更新 更多