使用AngularJS和jQuery修改DOM (slideDown/slideUp)

Modifying DOM (slideDown/slideUp) with AngularJS and jQuery

本文关键字:slideDown slideUp DOM AngularJS jQuery 修改 使用      更新时间:2023-09-26

我想用AngularJS实现一个slideDown/slideUp动画。我不能使用CSS3的过渡(不幸的是),因为height被设置为auto(我不想使用max-height的解决方案),所以我试图使用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吗?它是否尊重对关注点的分离?

或者,你可以使用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-hideng-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

注:必须包含jqueryangular-animate.js

我想展示一个如何使用ng-if完成的示例,因为我正在寻找一个解决方案,几个小时运行到多个完全不同的方法,仅与ng-show一起工作。你可以使用ng-ifng-show,如果你说你需要的指令只在变得可见时初始化。

使用jQuery slideDown/slideUp与ng-if,你也可以使用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的动画有一个合适的时间和地点。