【问题标题】:Call directive API method from 'parent' controller in AngularJS从 AngularJS 中的“父”控制器调用指令 API 方法
【发布时间】:2014-07-31 10:21:06
【问题描述】:

我有一种情况,我想创建自定义组件,它应该是可重用的,并提供公共 API 来改变它的状态。我试图通过使用指令和控制器构建组件来实现这一点。

我想做的只是:

customComponent.apiMethod1( Math.floor( Math.random() * 2 ) );

这里是 JSFiddle,应该可以解释我的情况:http://jsfiddle.net/7d7ad/4/

在第 9 行(当用户单击按钮时),我想调用第 22 行方法(自定义组件公共 API 方法)。有没有办法做到这一点?

【问题讨论】:

  • 由于您已经隔离了范围,因此您无法从您的范围调用指令中的函数。相反,您可以在服务中编写函数并在所有地方重用它
  • 你真的需要先重新审视 Angular。您使用 JQuery 选择器的方式确实不正确。
  • 你这是什么意思?我在这里看到的唯一错误是 DOM 操作是由控制器处理的,而不是指令。

标签: javascript angularjs angularjs-controller angular-directive


【解决方案1】:

您正在寻找Providers。共有三种不同的类型:工厂、服务和提供者。每个都有点不同,你可以看看this summary

提供者可以让您在应用程序的不同区域之间共享常用方法、函数和数据,而无需重复代码。

简短示例 - Fiddle

html

<div ng-app="myApp" ng-controller="testController">
    <button ng-click="ClickMe()">Random</button>
    {{display.value}}
</div>

javascript

angular.module('myApp', [])
.controller('testController', ['$scope','myService', function($scope, myService) {
    $scope.display =new myService();

    $scope.ClickMe = function() {
        $scope.display.apiMethod1();
    };
}])
.factory('myService', function() {
     function factory() {
          this.value = "Hello World";

          this.apiMethod1 = function() {
               this.value =  Math.floor( Math.random() * 2 );
          };
      }
      return factory;
});

【讨论】:

  • 我能否将此提供程序链接到指令,以便每个实例都有自己的“数据/API 范围”?又应该如何调用提供者方法引用指令实例?
  • 根据您设置工厂的方式,您可以让它们不共享范围,是的,您可以在指令中扩展工厂。话虽如此,我认为您正在错误地解决问题。为什么不在代码中使用ng-click 和其他角度方法。
  • 我更新了我的答案,以更好地举例说明我的建议,并包括一个工作小提琴。
【解决方案2】:

除了服务之外,您还可以将父指令与控制器一起使用。

这是一个如何工作的示例(底部的服务示例):

app.directive('parentDir', function() {
    return {
        controller: function($scope, $element) {
            var childFuns = [];
            this.registerFun = function(func) {
                childFuns.push(func);
            }
            //we will call this using ng-click
            $scope.onClick = function(){
                childFuns.forEach(function(func){
                   func.call(null,5)
                });
            }
        }
    }
})

在子指令中:

app.directive('customcomp', function() {
    return {
        restrict: 'E',
        scope: {},
        require: '^parentDir', //we "require" the parent directive's controller,
                               //which makes angular send it as the fourth
                               //argument to the linking function.
        template: '<h2>{{_currentNumber}}</h2>',
        link: function(scope, elm, attrs, ctrl) {
            scope._currentNumber = 0;
            scope.apiMethod1 = function(val) {
                scope._currentNumber = val;
            };
            //call the parent controller's registring function with the function
            ctrl.registerFun(scope.apiMethod1);
        }
    }
});

每个子指令都会“注册”一个函数,并且可以以任何您想要的方式从父指令存储和调用这些函数。

请注意,您应该将ng-click 用于带有角度的事件。

FIDDLE

下面是服务的外观:

app.service('funcs', function(){
    var funcs = [];
    this.register = function(func){ funcs.push(func)};   
    this.call = function(){
        funcs.forEach(function(func){
            func.call(null,5);
        })
    }
})

FIDDLE

【讨论】:

  • 我试图扩展您的第二个示例,以便您可以区分相同类型的实例(此处:jsfiddle.net/c3M2s/4)。我想知道是否真的有必要创建引用所有这些的服务(在我看来,这种方法不支持封装或可重用性)。
猜你喜欢
  • 1970-01-01
  • 2015-03-22
  • 1970-01-01
  • 1970-01-01
  • 2018-01-03
  • 1970-01-01
  • 2013-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多