web-dev-qa-db-ja.com

AngularJSとjQueryによるDOM(slideDown / slideUp)の変更

AngularJSでslideDown/slideUpアニメーションを実装しようとしています。 heightautoに設定されているので(残念ながら)CSS3のトランジションを使用できません(そして the max-height workaround を使用したくない)ため、jQueryを使用しようとしていますslideToggleメソッド。

次のマークアップがあるとします。

<ul>
    <li ng-repeat="entry in data">
        <span>{{entry.title}}</span>
        <a ng-click="clicked($event)" href>more?</a>
        <p>{{entry.description}}</p>
    </li>
</ul>

コントローラに次のメソッドを実装しました。

$scope.clicked = function($event) {
    var a = jQuery($event.target);
    var p = a.next();
    p.slideToggle();
};

[〜#〜]フィドル[〜#〜]

期待どおりに動作しているように見えても、DOMの変更はディレクティブ内でのみ行われることを理解しました。

AngularJS 'のドキュメント (私が少し軽いIMHOを見つけた)を読んだ後も、ディレクティブはまだ少し曖昧なので、次のディレクティブがAngularJSを尊重しているかどうか誰かに教えてもらえますか最高の評論かどうか?

.directive('testDirective', [
function() {
    return {
        restrict: 'A',
        scope: {
            entry: '=testDirective'
        },
        template: '<span>{{entry.title}}</span> ' +
                  '<a ng-click="clicked($event)" href>more?</a>' +
                  '<p>{{entry.description}}</p>',
        link: function(scope, element) {
            var p = jQuery(element.find('p'));
            scope.clicked = function($event) {
                p.slideToggle();
            };
        }
    };
}])

[〜#〜]フィドル[〜#〜]

改善できますか?ディレクティブ内でjQueryを許可できますか? 分離の懸念を尊重していますか?

20
sp00m

または、AngularJSの$animateを使用することもできます。

.animation('.slide', function() {
    var NG_HIDE_CLASS = 'ng-hide';
    return {
        beforeAddClass: function(element, className, done) {
            if(className === NG_HIDE_CLASS) {
                element.slideUp(done); 
            }
        },
        removeClass: function(element, className, done) {
            if(className === NG_HIDE_CLASS) {
                element.hide().slideDown(done);
            }
        }
    }
});

説明を表示または非表示にするには、ng-hideまたはng-showを使用します。

    <li ng-repeat="entry in data">
        <span>{{entry.title}}</span>
        <a ng-click="expand = !expand" href="#">more?</a>
        <p class="slide" ng-show="expand">{{entry.description}}</p>
    </li>

参照 JSFiddle

追伸jqueryおよびangular-animate.jsを含める必要があります

40
LostInComputer

ng-ifだけで機能する完全に異なる複数のアプローチに何時間も実行するためのソリューションを探していたので、ng-showでこれを行う方法の例を示したいと思います。表示されたときにのみ初期化されるディレクティブが必要な場合は、ng-if vs ng-showを使用できます。

ng-ifでjQuery slideDown/slideUpを使用するには、ngAnimateを使用することもできますが、enterleaveのフックを使用します。

app.animation('.ng-slide-down', function() {
  return {
    enter: function(element, done) {
      element.hide().slideDown()
      return function(cancelled) {};
    },
    leave: function(element, done) { 
      element.slideUp();
    },
  };
});

<div class="ng-slide-down" ng-if="isVisible">
     I will slide down upon entering the DOM.
</div>

これは、JSベースのさまざまなアプローチやCSSのみのアプローチを試しても、達成するのが驚くほど困難でした。結局、jQueryのアニメーションには時間と場所があります。