7

angleとjqueryを使用して、slideToggle関数を実装しました。この関数を1つの特定のHTML要素にのみ適用するために、ng-click関数内で1つのパラメーターを使用しています。コードは正常に機能しますが、ディレクティブとng-click関数を角度で実装する別のより良い方法が存在するかどうかを知りたいです。

index.html

<!DOCTYPE html>
<html ng-app="myApp" ng-controller="MainController">
<head>
    <title></title>
    <link type="text/css" rel="stylesheet" href="css/styles.css"/>
</head>
<body>
    <div>
        <input type="button" ng-click="toggle('first')" value="Toggle First">
        <input type="button" ng-click="toggle('second')" value="Toggle Second">
        <input type="button" ng-click="toggle('third')" value="Toggle third">
        <div class="div1" section="first" toggle="first" >
            <p>This is section #1</p>
        </div>
        <div class="div1" toggle="second">
            <p>This is another section #1</p>
        </div>
        <div class="div1" toggle="third">
            <p>This is 3 section #1</p>
        </div>
    </div>
</body>
<footer>
    <script src="js/jquery.min.js"></script>
    <script src="js/angular.js"></script>
    <script src="js/directives.js"></script>
</footer>
</html>

styles.css

.div1 {
    background: Brown;
    width: 200px;
    height: 200px;
    text-align: center;
}
.div1 p {
    position: relative;
    top: 50%;
}

directives.js

angular.module("myApp", []) //
    .controller('MainController', function($scope) {
        $scope.toggle = function(section) {
            console.log('<toggle function> section :' + section);
            $scope.section = section;
            $scope.$broadcast('event:toggle');
        }
    }) //
    .directive('toggle', function() {
        return function(scope, elem, attrs) {
            scope.$on('event:toggle', function() {
                if(attrs.toggle == scope.section){
                    elem.slideToggle('fast');
                }
            });
        };
    });

私自身の懸念の1つは、ディレクティブとスコープの間で通信する方法です。

        $scope.section = section;

        if(attrs.toggle == scope.section){

より良いAngularの実装のためのアドバイスをいただければ幸いです。

ありがとう

4

3 に答える 3

14

プランカーのデモ: http://plnkr.co/edit/u69puq?p=preview

参考までに、執筆時点で、AngularJS チームはngAnimateディレクティブを追加しています。これは、jQuery が現在提供しているほとんどのアニメーション機能 (スライド、フェードなど) を (うまくいけば) 提供します。

HTML

<div data-ng-controller="MainController">      
    <input type="button" value="Toggle First" ng-click="box1=!box1">
    <input type="button" value="Toggle Second" ng-click="box2=!box2">
    <input type="button" value="Toggle third" ng-click="box3=!box3">

    <div class="div1" data-slide-toggle="box1" data-slide-toggle-duration="100" >
        <p>This is section #1</p>
    </div>
    <div class="div2" data-slide-toggle="box2" data-slide-toggle-duration="2000">
        <p>This is another section #1</p>
    </div>
    <div class="div3" data-slide-toggle="box3">
        <p>This is 3 section #1</p>
    </div>
</div>

JS

var myApp = angular.module("myApp", []);

myApp.controller('MainController', function($scope) {
  $scope.box1 = $scope.box2 = $scope.box3 = true;
});

myApp.directive('slideToggle', function() {  
  return {
    restrict: 'A',      
    scope:{
      isOpen: "=slideToggle"
    },  
    link: function(scope, element, attr) {
      var slideDuration = parseInt(attr.slideToggleDuration, 10) || 200;      
      scope.$watch('isOpen', function(newVal,oldVal){
        if(newVal !== oldVal){ 
          element.stop().slideToggle(slideDuration);
        }
      });
    }
  };  
});
于 2013-03-17T18:48:48.517 に答える
0

Peter の解決策を試した後、slideToggle の下のディレクティブが親スコープにアクセスできないことがわかります。これが私の解決策です。

evoapp.directive('slideToggle', function() {
    return {
        restrict: 'A',
        scope: false ,
        link: function(scope, element, attr) {
            var slideDuration = parseInt(attr.slideToggleDuration, 10) || 200;
            var toggle = attr.toggle ;

            scope.$watch(toggle, function(newVal,oldVal){
                if(newVal !== oldVal){
                    element.stop().slideToggle(slideDuration);
                }
            });
        }
    };
});
于 2013-10-10T15:37:15.917 に答える