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

Angularjs 从链接调用角度指令控制器方法,angularjs,hyperlink,controller,typescript,directive,Angularjs,Hyperlink,Controller,Typescript,Directive,我试图在typescript中编写一个angular指令,它使用一个控制器和一个模板来显示从web api加载的数据。加载的数据应取决于应用指令的视图控制器中的属性,如下所示: <my-directive watched-prop="ctrl.dataProperty"></my-directive> module Test.Directives { class MyDirectiveController { public data: any;

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

<my-directive watched-prop="ctrl.dataProperty"></my-directive>
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>

其思想是,每次更改上述dataProperty时,都应加载一些新数据并将其应用于指令的模板。为了实现这一点,我想使用以下方法:

<my-directive watched-prop="ctrl.dataProperty"></my-directive>
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>
模块测试指令{
类MyDirectiveController{
公共数据:任何;
//Nginect
构造函数(/*注入参数*/){}
publictestmethod():void{
//做一些有用的事情并设置数据属性
}
}
函数linkImpl(作用域:ng.IScope,元素:ng.IAugmentedJQuery,属性:ng.IAttributes,ctrl:ng.INgModelController){
var watcher=范围。$watch(“watchedProp”,(newValue,oldValue)=>{
如果(新值!==旧值){
//在控制器中更改调用testMethod…(如何更改?)
}
});
作用域。$on(“$destroy”,()=>{watcher()});
}
myDirective.$inject=[“dependency1”、“dependency2”];
导出函数myDirective(/*injectparams*/):ng.IDirective{
var指令={
限制:“E”,
templateUrl:“../myDirectiveTemplate.tpl.html”,
作用域:{“watchedProp”:“=”},
链接:linkImpl,
控制器:MyDirectiveController,
controllerAs:“directiveCtrl”
};
返回指令;
}
}
指令的模板的工作原理如下:

<my-directive watched-prop="ctrl.dataProperty"></my-directive>
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>
{{directiveCtrl.data}
我的问题是,当链接方法中触发更改时,我不明白如何与指令自己的控制器通信?有没有更好、更“正确”的方法来做我想做的事情?(对于在指令中同时使用link和controller是否会被认为是错误的,我有点困惑。)

希望我已经解释清楚了我想要完成的是什么,我很感激任何关于如何正确完成的建议


/关于克里斯托弗

我已经重写了我的代码,现在它似乎可以工作了,但是我仍然不确定这是否是解决这个问题的“最佳角度”方法,但它可以工作,这就是我想要的:

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;
        }
    }
}
模块测试指令{
导出接口IMyDirectiveController{
testMethod():void;
}
导出类MyDirectiveController实现IMyDirectiveController{
公共数据:任何;
//Nginect
构造函数(/*注入依赖项(例如web api调用的服务)*/){
publictestmethod():void{
//做些有用的事
}
}
导出类MyDirective实现ng.IDirective{
restrict=“E”;
templateUrl=“../myDirectiveTemplate.tpl.html”;
作用域={watchedProp:“=”};
控制器=MyDirectiveController;
controllerAs=“directiveCtrl”;

//bindToController如果我能给你一个提示的话-我几乎不使用link方法(除非真的需要它的特性,例如传递父elments控制器)。只考虑控制器和视图…按我的方式。最新功能如
bindToController
和angular 2.0的概念…可能会成为一个论据。您好,感谢您花时间阅读我的问题和回答。据我所知,使用bindToController会将我的隔离范围绑定到指令自己的控制器,我不会这样做您可以访问watchedProp,它引用视图控制器(父级?)内的属性我的问题是,我希望能够在该属性上设置一个watch,并且能够使用单独的指令控制器/etmplate来显示新数据。也许我完全弄错了?我相信,scope可以自行清除它的
$watch
$on('$destroy',
用于自定义清除,如DOM事件侦听器等。