2015-10-17 90 views
1

我正在尝试编写一个使用控制器和模板一起显示从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> 

我的问题是,我不明白如何与指令的传达在链接方法中触发更改时自己的控制器?有没有更好,更“正确”的做我想做的方式? (我有点困惑,我是否认为在指令中同时使用链接和控制器都是错误的。)

希望我已经解释了它是什么我试图完成清晰,我很感激任何关于如何做到这一点的指针。

/问候的Kristofer

+0

如果我可以给你一个提示 - 我几乎不使用链接方法*(除非真的需要它的功能,例如传递父类控制器)*。想想控制器和视图......只是我的方式。作为'bindToController'和角度2.0的概念的最新功能...可能是一个参数。 –

+0

嗨,并感谢您花时间阅读我的问题和答复。据我了解,它使用bindToController将我的孤立范围绑定到指令自己的控制器,我将不再能够访问watchedProp,它引用视图控制器内的属性(父?)我的问题是,我希望能够在该属性上设置一个监视,并且能够让我单独的指令控制器/ etmplate显示新的数据。也许我错了吗? – Kristofer

回答

2

我已经重写我的代码,现在它似乎是工作,但我仍然不知道这是否是“最佳角度”的方式来解决这个问题,但它的作品,这就是我所追求的:

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; 
     } 
    } 
} 

我想我已经有更多的耐心和过兵上发布我的问题之前,但也许写作的角度指令为打字稿类时,别人会觉得它有用。

编辑:我不明白的一个小问题是,我不能使用IMyDirective.create来注册我的指令,而是必须使用IMyDirective.create()作为依赖注入来处理指令构造函数... //干杯

+1

我相信,范围可以自行清除其“$ watch”。 '$ on('$ destroy','是用于你的自定义清理,比如DOM事件监听器等。 –