Angular 确保在打开另一个开关时关闭开关

Angular ensure toggle is closed if another one is opened

有两个不同的 div,可以在 Angualar 应用程序中打开和关闭,但要确保打开一个时另一个关闭。看起来这在 NG 中应该足够简单,但对 Angular 来说仍然是新的。有人有任何指示吗?

在这里做了一个例子fiddle: JS Fiddle

示例如下:

 <body ng-app="simpleToggle">
   <div ng-controller="AppCtrl">
    <button ng-click="toggleCustom1()">Custom</button>
    <span ng-hide="custom1">
        <h2>Custom 1 is showing but Custom 2 should not be if it was already opened</h2>
    </span>
    <span ng-show="custom1"></span>
</div>

<div ng-controller="App2Ctrl">
    <button ng-click="toggleCustom2()">Custom2</button>
    <span ng-hide="custom2">
        <h2>Custom 2 is showing but Custom 1 should not be if it was already opened.</h2>
    </span>
    <span ng-show="custom2"></span>
</div>
 </body>

 angular.module('simpleToggle', [])
.controller('AppCtrl',['$scope', function($scope){
    $scope.custom1 = true;
    $scope.toggleCustom1 = function() {
        $scope.custom1 = $scope.custom1 === false ? true: false;
    };
 }])
.controller('App2Ctrl',['$scope', function($scope){
    $scope.custom2 = true;
    $scope.toggleCustom2 = function() {
        $scope.custom2 = $scope.custom2 === false ? true: false;
    };
 }]);

此处您处理的是作用域层次结构,您将希望使用其中一种机制在控制器之间进行协调。一些选项是:

  1. 使用 $rootScope
  2. 使用消息

我已将您的示例更新为在此处使用 $rootScope http://jsfiddle.net/4q7hrpc5/3/

首先,创建一些东西来初始化 $rootScope。我创建了一个外部控制器并将另外两个控制器包裹在该控制器中。这是更新后的 HTML:

<body ng-app="simpleToggle">
    <div ng-controller="OuterCtrl">
        <div ng-controller="AppCtrl">
            <button ng-click="toggleCustom1()">Custom</button>
            <span ng-hide="!custom1">
                <h2>Custom 1 is showing but Custom 2 should not be if it was already opened</h2>
            </span>
        </div>

        <div ng-controller="App2Ctrl">
            <button ng-click="toggleCustom2()">Custom2</button>
            <span ng-hide="!custom2">
                <h2>Custom 2 is showing but Custom 1 should not be if it was already opened.</h2>
            </span>
        </div>
    </div>
</body>

这是控制器的代码:

angular.module('simpleToggle', [])
    .controller('OuterCtrl', ['$rootScope', function($rootScope) {
        $rootScope.custom1 = false;
        $rootScope.custom2 = false;
    }])
    .controller('AppCtrl',['$rootScope', '$scope', function($rootScope, $scope){
        $scope.toggleCustom1 = function() {
            $rootScope.custom1 = !$rootScope.custom1;
            $rootScope.custom2 = false;
        };
}])
    .controller('App2Ctrl',['$rootScope', '$scope', function($rootScope, $scope){
        $scope.toggleCustom2 = function() {
            $rootScope.custom2 = !$rootScope.custom2;
            $rootScope.custom1 = false;
        };
}]);

现在这个特定的技术只适用于少数需要协调的事情。如果您有大量需要协调的此类事物,消息或服务可能会更好。另一种选择是将它们全部放入同一个控制器中。

使用指令处理 DOM 内容是一种很好的做法。我使用 .next() 来获取下一个跨度。或者您可以使用其他选择器来获取它。

元素的文档:https://docs.angularjs.org/api/ng/function/angular.element

在这里工作 here

html:

<body ng-controller="MainCtrl">
    <div>
        <button change-toggle>Custom</button>
        <span id="span1" class="toggle-show-css">
            <h2>Custom 1 is showing but Custom 2 should not be if it was already opened</h2>
        </span>
    </div>
    <div>
        <button change-toggle>Custom2</button>
        <span id="span2" class="toggle-show-css">
            <h2>Custom 2 is showing but Custom 1 should not be if it was already opened.</h2>
        </span>
    </div>
</body>

css

.toggle-hide-css {
  visibility: hidden;
}

.toggle-show-css {
  visibility: visible;
}

指令

app.directive('changeToggle', ['$location', function($location) {
  return {
    restrict: 'A',
    link: function(scope, elem, attrs) {
      elem.bind('click', function(event) {
        var spanner = elem.next();
        if(spanner.hasClass("toggle-show-css")) {
          elem.parent().parent().find('span').removeClass("toggle-show-css");
          elem.parent().parent().find('span').addClass("toggle-hide-css");
          spanner.removeClass("toggle-show-css");
          spanner.addClass("toggle-hide-css");
        } else {
          elem.parent().parent().find('span').removeClass("toggle-show-css");
          elem.parent().parent().find('span').addClass("toggle-hide-css");
          spanner.removeClass("toggle-hide-css");
          spanner.addClass("toggle-show-css");
        }
      });
    }
  }
}]);