我是否需要为Angular指令提供模板以包装内容?

时间:2014-01-14 18:00:29

标签: angularjs angularjs-directive

我想我可能会试图将一个方形钉固定在这里的圆孔中。我想要做的是定义一个约定,将一些通用的JavaScript功能附加到特定的HTML属性。

例如,假设我有这个HTML:

<nav my-nav>
  <ul>
    <li class="tab">1</li>
    <li class="tab">2</li>
    <li class="tab">3</li>
  </ul>
</nav>

我对Angular的非常原始的理解是我应该创建一个指令。从the documentation,我可以看到,因为我想要包装任意内容,所以我需要使用transclude属性。但是,当我尝试<nav>中的元素消失时。

从试验和错误中我看到Angular希望我提供一个template属性来包装内容。所以我用一个毫无意义的<div>标签来做到这一点,这对我来说是非常多余的。

myApp.directive('myNav', function() {
  return {
    // I get why this is necessary
    transclude: true,

    // I get why this is necessary
    link: function(scope, element) {
      // This is where my custom JavaScript logic goes
    }

    // This feels unnecessary to me
    template: '<div ng-transclude></div>',
  };
});

我是否反对这里的粮食?使用Angular有更惯用的方法吗?我是不是甚至不愿意使用Angular来做这件事(也就是说,标准方法是在“Angular”之外为此目的编写自定义JavaScript吗?)

2 个答案:

答案 0 :(得分:1)

是的,指令是处理DOM操作的Angular方法。

但是如果您只想将事件监听器添加到某些html中,则无需担心转换。

例如,这是一个演示,可以添加一个点击监听器(当然,您可以轻松地将鼠标悬停等等)添加到附加的dom元素和每个li元素(仅用于演示目的):

myApp.directive('myNav', function() {
  return {
    link: function(scope, element) {
        // Add event listener to whole dom element
        element.bind('click', scope.clicked); 

        // Individual event listeners on each li element
        liElems= element.find("li");
        for (i = 0;i<liElems.length;i++)
          angular.element(liElems[i]).bind('click', scope.clicked); 
    }
  };
});

demo fiddle

答案 1 :(得分:0)

你不必用div包装它,只需使用$ transclude:

myApp.directive('myNav', function() {
  return {

    transclude: true,

    link: function(scope, element, attr, ctrl, $transclude) {
       $transclude(function(clone){
          element.append(clone);
       });
    }

  };
});

ng-transclude只是简单案例的快捷方式