无法在按钮单击上调用Angular Directiive方法

时间:2017-01-08 11:42:08

标签: angularjs angularjs-directive

我正在尝试从调用控制器上点击按钮调用指令方法。

这是指令代码:

  myApp.directive("helloDirective", function() {
    return {
      restrict: "E",
      template: '<input type="text" data-ng-model="model.msg" />',
      scope: {},
      bindToController: {
        param: "="
      },
      controller: 'helloDirectiveController',
      controllerAs: 'model'
    }
  })
  .controller("helloDirectiveController", function() {
      var self = this;
      self.actions = {
        get: function() {
          return self.msg;
        },
        set: function(msgData) {
          self.msg = msgData;
        }
      });

我已从控制器调用getset方法..

myApp.controller("indexController", [function() {
    var self = this;
    self.helloParam ={};
    self.get = function() {
      //how to call the Directive get method from here
    }
  }]);

我试图创建一个小提琴here

plnkr

2 个答案:

答案 0 :(得分:0)

想法

对我而言,针对您的问题最清晰的解决方案(目前为止)是Angular Material开发人员使用的解决方案(我不知道他们是作者,但我在那里找到了)。我在我的项目中曾经使用过它,它就像一个魅力。

这个想法是为指令创建一个全球注册表&#39;动作。指令将由唯一ID存储在那里。我们还可以创建专用于每个指令的服务,以防万一我们需要一些外部逻辑。

解决方案

1。组件注册表

首先,我们需要一个组件注册表。它可以是一个非常简单的服务:

angular.module('app');
    .service('$componentsRegistry', function() {
        var self = this;
        var components = {};

        self.put = function(id, actions) {
            components[id] = actions;
        }

        self.get = function(id) {
            return components[id];
        }
    })

组件注册表具有按ID存储和获取组件的方法。当然,可能会有更多的方法,它们可能会更复杂,但这只是一个简单的例子。

2。为我们的指令服务

我们说我们有一个简单的show-message指令,因此我们可以创建$showMessageService

angular.module('app')
    .service('$showMessageService', ['$componentsRegistry', function($componentsRegistry) {
        return function(id) {
            return $componentsRegistry.get(id);
        }
    }])

目前,该服务的唯一任务是返回我们指令的动作。但当然,它可以在将来扩展。

3。指令的代码

我们需要的最后一件事是show-message指令:

angular.module('app')
    .directive('showMessage', function($componentsRegistry) {
        return {
            restrict: 'E',
            scope: {
                directiveId: '@' // Unique id is passed from the view
            },
            template: '<div>{{ text }}</div>',
            link: function(scope) {
                scope.text = 'TEST TEXT';

                // Create actions
                scope.actions = {
                    set: function(value) {
                        scope.text = value;
                    }
                }    

                // Store actions in the components registry
                $componentsRegistry.put(scope.directiveId, scope.actions);
            }
        }
    })

在链接功能中,我们只需在组件注册表中注册我们的操作。我们从视图中传递唯一的id,以便开发人员可以在视图/控制器中控制它。

使用示例

现在我们终于可以在我们的应用程序中使用该指令了。这是一个简单的代码,显示了如何做到这一点:

视图

<div ng-controller="testController as test">
    <show-message directive-id="testDirective"></show-message>
    <button ng-click="test.changeText()">CHANGE</button>
</div>

控制器

angular.module('app')
    .controller('testController', function(['$showMessageService', $showMessageService) {
        var self = this;

        self.changeText = function() {
            $showMessageService('testDirective').set('NEW');
        }
    }])

答案 1 :(得分:0)

我更改了指令代码,将Controller代码移至link并且工作正常。

testApp.directive("helloDirective", function () {
    return {
        restrict: "E",
        template: '<input type="text" data-ng-model="model.msg" />',
        scope: {},
        bindToController: {
            param: "="
        },
        link: function (scope, element, attrs) {
            var self = scope.model;

            var assignMethod = function () {
                if (self.param == undefined) {
                    self.param = {};
                }
                self.param.actions = {
                    get: function () {
                        return self.msg;
                    },
                    set: function (msgData) {
                        self.msg = msgData;
                    }
                };
            };
            assignMethod();
        },
        controller: function () { },
        controllerAs: 'model'
    }
});

现在我可以调用指令get Method来调用控制器,如

  self.helloParam = {};

  self.click = function () {
        alert(self.helloParam.actions.get());
    }