Angular JS-需要与页面上的所有指令进行通信,这些指令来自只运行一次的服务中的代码

Angular JS - Need to communicate with all directives on page from code in service which only runs once

本文关键字:指令 运行 代码 服务 一次 通信 JS- Angular      更新时间:2023-09-26

我创建了一个基本的下拉指令,它运行良好(正确打开和关闭等)。

我尝试创建了一个管理器服务,它可以跟踪每个页面上有多少下拉列表,并允许您在打开下拉列表时"关闭其他",在单击页面正文但不在下拉列表上时"关闭所有"。

问题是,我想在调用"close-all"事件的文档主体上放置一个jquery事件,并且我只希望它绑定一次。如果我把它放在经理服务的工厂方法中,我可以得到这两个工作,但从那里它不能调用要返回的工厂的方法。

我还试着从工厂没有返回的代码部分关闭它们,因为我可以从那里访问数组,但我不能访问$scope$从服务中申请。

你知道我该怎么做吗?

为了简洁起见,下面是一些删除了大部分代码的代码。

angular.module('directives')

.factory('dropdownManager', function() {
    var dropdowns = [];

    // Close all when the document is clicked, unless the click was on a dropdown
    $('BODY').on('click', function (event) {
        // NEED TO ACCESS CLOSE ALL FUNCTION FROM HERE
    });

    return {
        addItem: function(itemScope) {
            // Add Item to Array
        },

        removeItem: function(itemScope) {
            // Add Item from array 
        },
        closeAll: function(openItem){
            // Loop through array and close them all using item.isOpen = false;
        },

    };
}])
.directive('six4Dropdown', function (dropdownManager) {
    // Dropdown directive code goes here
});

您可以为此创建自定义指令,请参阅下面的演示

var app = angular.module('app', []);
app.directive('myDirective', function(dropdownManager) {
  return {
    link: function(scope, element, attr) {
      element.on('click', function() {
        scope.$apply(function() {
          dropdownManager.closeAll();
        });
      });
    }
  };
});
app.factory('dropdownManager', function() {
  var dropdowns = [{
    id: 1,
    isOpen: true
  }, {
    id: 2,
    isOpen: true
  }];

  return {
    addItem: function(itemScope) {
      // Add Item to Array
    },
    removeItem: function(itemScope) {
      // Add Item from array 
    },
    closeAll: function(openItem) {
      console.log("SA");
      angular.forEach(dropdowns, function(item) {
        item.isOpen = false;
      });
    },
    dropdowns: dropdowns

  };
});
app.controller('firstCtrl', function($scope, dropdownManager) {
  $scope.data = dropdownManager;
});
<html ng-app="app" my-directive="">
<head>
  <script src="//code.jquery.com/jquery.min.js"></script>
  <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
  <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
  <div ng-controller="firstCtrl">
    <pre>{{data.dropdowns | json}}</pre>
  </div>
</body>
</html>

我在文档级别使用了single.bind,并使用$rootScope调用了dropdownManager.closeAll();关键是从工厂初始化代码内部访问作用域。唯一的方法似乎是使用$rootScope。