附加相同元素的多个指令

时间:2015-03-07 00:46:52

标签: angularjs

我正在尝试将一组指令附加到相同的DOM元素(类似于此

Angular HTML

<div one two></div>

和HTML结果是这样的

    <div one two>
      <h1>one</h1><!--this one added by the 'one' directive-->
      <h2>two</h2><!--this one added by the 'one' directive-->
   </div>

我不确定如何使用指令完成,而无需使用Jquery

进行追加

var app = angular.module('app', []);

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
}).
directive('one',function(){return{restrict:'A',template:'<h1>one</h1>'};}).
directive('two',function(){return{restrict:'A',template:'<h2>two</h2>'};})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html ng-app="app">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.14/angular.js" data-semver="1.3.14"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <div one two></div>
  </body>

</html>

similar question with no answer

Another question with no answer

2 个答案:

答案 0 :(得分:1)

你不能在同一个元素上有两个指令,它们都包含一个模板:只有一个会覆盖另一个。

一种解决方案可能是在two模板中添加one指令,如下所示:

&#13;
&#13;
var app = angular.module('app', []);

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
}).
directive('one',function(){return{restrict:'A',template:'<h1>one</h1><div two></div>'};}).
directive('two',function(){return{restrict:'A',template:'<h2>two</h2>'};})
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html ng-app="app">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.14/angular.js" data-semver="1.3.14"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <div one></div>
  </body>

</html>
&#13;
&#13;
&#13;

另一种解决方案,如果您不希望two始终属于one,则只需将两者放在HTML中即可,如下所示

&#13;
&#13;
var app = angular.module('app', []);

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
}).
directive('one',function(){return{restrict:'A',template:'<h1>one</h1>'};}).
directive('two',function(){return{restrict:'A',template:'<h2>two</h2>'};})
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html ng-app="app">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.3.x" src="https://code.angularjs.org/1.3.14/angular.js" data-semver="1.3.14"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <div one></div>
    <div two></div>
  </body>

</html>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

您无法单独使用模板参数执行所需操作。模板参数只是在指令编译函数中执行类似以下操作的简写:

compile: function(element, attr) {
    element.empty();
    element.append(template);
}

如果在指令中包含模板属性,则会自动执行此操作。如果要覆盖此行为,只需让指令附加内容(不清空它),则只需要取消模板属性即可。所以你的两个指令是:

  .directive('one', function() {
    return {
      compile: function(element, attr) {
        element.append('<h1>one</h1>');
      }
    };
  })
  .directive('two', function() {
    return {
      compile: function(element, attr) {
        element.append('<h1>two</h1>');
      }
    };
  });

您可以在this Plunk

中查看

I've also included a version that uses a template from a file。这里唯一的问题是以这种方式加载模板需要使用链接。

  .directive('three', function($http, $compile, $templateCache) {
    return {
      link: function(scope, element, attr) {
        $http.get('template.html', {cache: $templateCache}).then(function(result){
          element.append($compile(result.data)(scope));
        });
      }
    };
  });

here is a version that uses link

  .directive('one', function($compile) {
    return {
      link: function(scope, element, attr) {
        element.append($compile('<h1>one</h1>')(scope));
      }
    };
  })
  .directive('two', function($compile) {
    return {
      link: function(scope, element, attr) {
        element.append($compile('<h1>two</h1>')(scope));
      }
    };
  });

有人认为你会注意到输出是倒退的。似乎&#34;一个&#34;在&#34; two&#34;之后附加,即使它在标记中排在第一位。如果我们添加了远程版本,只要模板是远程提供的,它就会起作用,但是当它从$ templateCache传递时它也会向后。

原因是它们都具有相同的优先级,并且&#34;链接&#34;以与编译相反的顺序调用。要修复,你可以简单地设置一个稍低的优先级(所以它最后编译,但首先链接)。

Heres a Plunk that does this with priority