从链接调用角度指令控制器方法

时间:2015-10-17 17:39:15

标签: angularjs hyperlink controller typescript directive

我试图在typescript中编写一个角度指令,该指令使用控制器和模板来显示从web-api加载的数据。加载的数据应该取决于控制器中应用指令的视图中的属性,如下所示:

<my-directive watched-prop="ctrl.dataProperty"></my-directive>

这个想法是,每次上面的dataProperty都被更改时,应该加载一些新数据并将其应用到指令的模板中。要做到这一点,我想用这样的东西:

module Test.Directives {
    class MyDirectiveController {

        public data: any;

        // ngInject
        constructor( /* Inject params */) {}

        public testMethod(): void {
            // Do something useful and set data-property
        }
    }

    function linkImpl(scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes, ctrl: ng.INgModelController) {
        var watcher = scope.$watch("watchedProp", (newValue, oldValue) => {
            if (newValue !== oldValue) {
               // on change call testMethod in controller... (how?)
            }
        });
        scope.$on("$destroy", () => { watcher() });
    }

    myDirective.$inject = ["dependency1", "dependency2"];

    export function myDirective(/* Inject params */): ng.IDirective {
        var directive = <ng.IDirective> {
            restrict: "E",
            templateUrl: "../myDirectiveTemplate.tpl.html",
            scope: { "watchedProp": "=" },
            link: linkImpl,
            controller: MyDirectiveController,
            controllerAs: "directiveCtrl"
        };

        return directive;
    }
}

该指令的模板可以这样工作:

<div>{{ directiveCtrl.data }}</div>

我的问题是,当链接方法触发更改时,我不明白如何与指令自己的控制器通信?是否有更好的,更正确的&#34;做我想要的方式? (我对在指令中同时使用链接和控制器是否被认为是错误感到有点困惑。)

希望我已经解释了我的目标是什么,我试图做到足够清楚,并且我很感激任何有关如何做到这一点的指示。

/关心Kristofer

1 个答案:

答案 0 :(得分:3)

我已经重写了我的代码,现在它似乎正在工作,但是我仍然不确定这是否是最好的角度&#34;解决这个问题的方法,但它起作用,这就是我所追求的:

module Test.Directives {
    export interface IMyDirectiveController {
        testMethod(): void;
    }

    export class MyDirectiveController implements IMyDirectiveController {

        public data: any;

        // ngInject
        constructor( /* Inject dependencies (e.g. service for web-api calls) */) {}

        public testMethod(): void {
            // Do something useful
        }
    }

    export class MyDirective implements ng.IDirective {
        restrict = "E";
        templateUrl = "../myDirectiveTemplate.tpl.html";
        scope = { watchedProp: "=" };
        controller = MyDirectiveController;
        controllerAs = "directiveCtrl";
        // bindToController <- not used as I don't want to loose watchedProp?

        // ngInject
        constructor(/* Inject dependencies (e.g. url-resolver for template) */) {}

        link(scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes, ctrl: IMyDirectiveController): void {
            var watcher = scope.$watch("watchedProp", (newValue, oldValue) => {
                if (newValue !== oldValue) {
                   ctrl.testMethod(); // <- Calls the controller-method
                }
            });
            scope.$on("$destroy", () => { watcher() });
        }

        static create(): ng.IDirectiveFactory {

            var directive: ng.IDirectiveFactory = (/* dependecies */): ng.IDirective => {
                return new MyDirective(/* dependencies */);
            }
            directive.$inject = [/* dependecies */];

            return directive;
        }
    }
}

我希望在发布我的问题之前我有更多的耐心并且在上面编写,但也许其他人会在将angular指令写成typescript类时发现它很有用。

编辑:我不能理解的一个小警告是我不能使用IMyDirective.create来注册我的指令,而是我必须使用IMyDirective.create()来执行依赖注入工作在指令构造函数中...... //欢呼