【问题标题】:Do I NEED to supply a template for an Angular directive to wrap content?我是否需要为 Angular 指令提供模板来包装内容?
【发布时间】:2014-01-14 18:00:29
【问题描述】:

我想我可能想在这里将一个方形钉子安装到一个圆孔中。我想做的是定义一个约定,将一些通用的 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 属性。但是,当我尝试让 &lt;nav&gt; 中的元素消失时。

通过反复试验,我看到 Angular 希望我提供一个 template 属性来包装内容。所以我用一个毫无意义的&lt;div&gt;标签来做这件事,这对我来说是多余的。

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)?

【问题讨论】:

    标签: angularjs angularjs-directive


    【解决方案1】:

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

    但是如果你只是想在一些 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

    【讨论】:

    • 我不想添加 HTML 来环绕内容;相反,我只想与已经存在的 HTML 进行交互(即,不会被删除)。换句话说,我基本上不想接触 HTML,只是结合了一些 JavaScript。这有意义吗?
    • 你能举个例子说明你想让javascript做什么吗?
    • 例如添加一些事件监听器。
    • 哦,当然,虽然您可能想在我的示例中使用ng-click - 这是您想要做的事情:jsfiddle.net/b5VZN/2
    • 有趣!所以看起来我根本不需要使用transclude,然后呢?
    【解决方案2】:

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

    myApp.directive('myNav', function() {
      return {
    
        transclude: true,
    
        link: function(scope, element, attr, ctrl, $transclude) {
           $transclude(function(clone){
              element.append(clone);
           });
        }
    
      };
    });
    

    ng-transclude 只是简单案例的捷径

    【讨论】:

    • $transclude 似乎是 undefined 当我完全按照您的示例进行操作时。任何预感为什么会这样? (我现在使用的是 Angular 1.0.1
    • 你应该升级:> 1.2.8
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-09
    • 1970-01-01
    • 1970-01-01
    • 2020-03-24
    • 2017-10-02
    • 2020-03-29
    相关资源
    最近更新 更多