web-dev-qa-db-ja.com

Angularを使用して、クリックイベントを要素にバインドし、クリック時に兄弟要素を上下にスライドさせるにはどうすればよいですか?

私はAngularで作業していますが、通常jQueryを使用していることを行うのに問題があります。

クリックイベントを要素にバインドし、クリック時に兄弟要素を上下にスライドさせたい。

これがjQueryの外観です。

$('element').click(function() {
    $(this).siblings('element').slideToggle();
});

Angularを使用して、マークアップの関数にng-click属性を追加しました。

<div ng-click="events.displaySibling()"></div>

そして、これが私のコントローラーの外観です:

app.controller('myController', ['$scope', function($scope) {

    $scope.events = {};

    $scope.events.displaySibling = function() {
        console.log('clicked');
    }

}]);

これまでのところ、これは期待どおりに機能していますが、スライドを完成させる方法がわかりません。どんな助けも大歓迎です。

更新

持っていたものをディレクティブに置き換えました。

私のマークアップは次のようになります。

<div class="wrapper padding myevent"></div>

コントローラーにあったものを削除し、新しいディレクティブを作成しました。

app.directive('myevent', function() {
    return {
        restrict: 'C',
        link: function(scope, element, attrs) {
            element.bind('click', function($event) {
                element.parent().children('ul').slideToggle();
            });
        }
    }
});

ただし、スライドトグルを機能させることはできません。 slideToggle()がAngularでサポートされているとは思わない。助言がありますか?

18
Michael Lynch

あなたが話している行動について正確にはわかりませんが、少し違う方法で考えることをお勧めします。 jQueryが少なく、角度があります。

つまり、次のようなHTMLを用意します。

<div ng-click="visible = !visible"></div>
<div ng-show="visible">I am the sibling!</div>

その後、ng-animateのビルドを使用して兄弟スライドを作成できます- yearofmoo$animateの仕組みの優れた概要を示しています。

この例は、HTMLに表示ロジックを配置できるほど単純ですが、それ以外の場合は、次のように、ルールとしてコントローラーに配置することをお勧めします。

<div ng-click="toggleSibling()"></div>
<div ng-show="visible"></div>

コントローラ:

app.controller('SiblingExample', function($scope){

  $scope.visible = false;

  $scope.toggleSibling = function(){
    $scope.visible = !$scope.visible;
  }

});

この種のコンポーネントは、ディレクティブをすべて適切にパッケージ化するディレクティブの主要な候補でもあります。

12
Ed Hinchliffe
app.directive('slideMySibling', [function(){
  // Runs during compile
  return {
    // name: '',
    // priority: 1,
    // terminal: true,
    // scope: {}, // {} = isolate, true = child, false/undefined = no change
    // controller: function($scope, $element, $attrs, $transclude) {},
    // require: 'ngModel', // Array = multiple requires, ? = optional, ^ = check parent elements
    restrict: 'A', // E = Element, A = Attribute, C = Class, M = Comment
    // template: '',
    // templateUrl: '',
    // replace: true,
    // transclude: true,
    // compile: function(tElement, tAttrs, function transclude(function(scope, cloneLinkingFn){ return function linking(scope, Elm, attrs){}})),
    link: function($scope, iElm, iAttrs, controller) {
      iElm.bind("click", function(){
         $(this).siblings('element').slideToggle();
      })
    }
  };
}]);

使い方は次のようになります

<div slide-my-sibling><button>Some thing</button></div><div>Some sibling</div>

上記のすべての「コード」は単なる例であり、実際にはテストされていないことに注意してください。

http://plnkr.co/edit/qd2CCXR3mjWavfZ1RHgA

コメントで述べたように、これは理想的なセットアップではありませんが、ビューの構造に関するJavascriptがまだあるので理想的ではありません。理想的には、一方が他方を必要とするいくつかのディレクティブで、またはイベントを使用してこれを行うでしょう($ emit、$ broadcast、$ onを参照)。

JavaScriptを使用してディレクティブで子を「プログラムで」作成し、ディレクティブがどのコンテキストで使用されているかわからないという問題を回避することもできます。これらの問題を解決する方法はたくさんありますが、機能的に機能するため、再利用性、安定性、テストなどのために注目に値します。

5
shaunhusain

このリンクごとに: https://docs.angularjs.org/api/ng/function/angular.element

コードスニペットのAngularJs要素は、関連要素のJQuery DOMオブジェクトを表します。 JQuery関数を使用する場合は、angularロード前にJQueryライブラリを使用する必要があります。詳細については、上記のリンクを参照してください。

0
Ravi Kanasagra