许多以 jquery 为中心的 Dom 工作在指令 link 函数中进行 - 这是错误的吗?

Lots of jquery-centric Dom work going on in directives link function - is this wrong?

我正在编写我的第一个指令 - 一个简单的弹出窗口,它在鼠标悬停(或触摸)时显示一些内容。看来我的 link 函数基本上是一些功能的包装器,否则我只是插入 jquery 世界中的一个函数。这是否正确 - 想知道是否有更以 angular 为中心的方法来实现这一点?

http://jsfiddle.net/wx8ydotr/4/

core.directive('popover', ['isTouchDevice', function (isMobileDevice) {
    return {
    restrict: 'A',
    link: function (scope, el, attrs) {
        el.addClass("popover");
        if (isMobileDevice) {
            el.bind("touchstart", function (e) {
                show();

            });
        } else {
            el.bind("mouseover", function (e) {
                show();

            });
             el.bind("mouseout", function (e) {
                hide();

            });
        }

        function show() {
         el.find('div').addClass('show');

        }

        function hide() {
            el.find('div').removeClass('show');            
        }
    }
  };
}]);

我的两分钱,我建议让你的 html 更明确。尝试将您的视图表示为模型并在 link 函数中初始化您的模型。

例如,请考虑以下 HTML 片段

<div ng-class="{ 'fade-in': showResults, 'fade-out': !showResults }"></div>

showResults 变量绑定到可在指令的 link 函数中访问的 $scope。根据条件,您可能想要设置 -

$scope.showResults = true/false;

在您的 link 函数中。这样做会使您的视图更具声明性,而不是在 DOM 上操作,您将 DOM 表示为视图模型并在视图模型上操作。

希望这对您有所帮助。

在使用 Angular 时,您应该尽量忘记 jQuery。您可以按照@swazza85 的建议使用 ng-class,而不是像您那样添加 类,或者简单地使用 ready-made 指令 ng-showng-hideng-mouseoverng-touch.

实现您现在所拥有的最快最简单的方法是

<div ng-mouseover="show = true" ng-mouseleave="show = false">Some text</div>
<div ng-show="show">Initially hidden</div>

不幸的是,没有指令捕获 touchstart 事件,但您可以通过将这些事件绑定到指令的 link 函数中来解决这个问题,正如您已经完成的那样。

一种更 angular 编写您的意图的方法,包装为指令,可能是以下内容。

HTML 模板

<body ng-controller="Ctrl as vm">
  <pop content="vm.val1" hover="vm.val2"></pop>
</body>

JavaScript

app.controller('Ctrl', function() {
  this.val1 = 'Touch or move mouse over the label';
  this.val2 = '...I haz appeared!!1';
});

app.directive('pop', function() {
  return {
    restrict: 'E',
    scope: { 
      content: '=', 
      hover: '='
    },
    template: '<div ng-mouseover="toggle(true)" ng-mouseleave="toggle(false)">' +
              '  <h4><span class="label label-default">{{ content }}</span></h4>' +
              '</div>' + 
              '<div ng-show="show" class="alert alert-info">{{ hover }}</div>',
    link: function(scope, element) {
      scope.toggle = function(val) {
        scope.show = val;
      };

      element.bind('touchstart', toggle, true);
      element.bind('touchend', toggle, false);
    }
  };
});

相关插件在这里http://plnkr.co/edit/JjydPL