外AngularJS指令不能正确构建内部指令

时间:2013-10-31 20:40:32

标签: javascript html angularjs angularjs-directive angularjs-scope

使用AngularJS 1.0.8,我正在尝试创建一些可重用的指令来创建一个Web开发人员可以编写具有许多属性的单个“顶级”指令的情况,而这个指令又具有包含其他指令的模板,它们本身可能包含其他指令等。

我遇到的问题是让“内部”模板了解顶级属性。我认为这将是一个普遍存在的问题,但从我的研究中看,并没有其他人在问这个问题。

我创建了此Plunker来显示问题:

<!DOCTYPE html>
<html ng-app="outerInnerDirectivesApp">
<head>
    <title>Outer/Inner Directives</title>
</head>
<body>
<div>Single level directive follows:</div>
<single-level-directive single-level-id="single123"></single-level-directive>
<div>Outer/inner directive follows (Expecting "outer123"):</div>
<outer-directive outer-id="outer123"></outer-directive>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
<script src="app.js"></script>
<script src="directives.js"></script>
</body>
</html> 

在Plunker中,

  1. 单级指令有效,我认为是显示数据的标准方法。

  2. 外部指令和内部指令不起作用。

  3. 我期望与这些相关的是

    (i)outerDirective编译/链接以生成html

    <inner-directive inner-id="outer123"></inner-directive>
    

    然后

    (ii)innerDirective编译/链接以生成html

    <div>outer123</div>
    

    但是在步骤(ii)我得到了

    <inner-directive inner-id="" class="ng-isolate-scope ng-scope">
       <div class="ng-binding"></div>
    </inner-directive>
    

    因此innerDirective会生成一个空div。

    事实上,如果我将outer-template.html更改为

    <div>{{outerId}}<div>
    

    然后值正确显示,所以它看起来像scope.outerId在正确的位置可用,但Angular对我尝试以我的方式使用它感到高兴。

    期望Angular这样做是否合理?如果是这样,我错过了什么?如果没有,那么您认为从简单的指令集构建更复杂的屏幕是一种明智的替代方式?

2 个答案:

答案 0 :(得分:1)

如果您要设计具有隔离范围的指令,我建议使用隔离范围来定义您要使用的属性类型:

outerInnerApp.directive("outerDirective", function() {
  return {
    restrict: "E",
    scope: {
      outerId: '@'
    },
    link: function(scope, element, attrs) {

    },
    templateUrl: "outer-template.html"
  };
});
outerInnerApp.directive("innerDirective", function() {
  return {
    restrict: "E",
    scope: {
      innerId: '='
    },
    link: function(scope, element, attrs) {

    },
    templateUrl: "inner-template.html"
  };
});

这是working plunker

您的外部指令正在使用属性中定义的值。因此,要将值传递到隔离范围,我们可以使用@。然后内部范围通过绑定变量。因此,我们可以使用=来设置绑定属性。

答案 1 :(得分:0)

对此有更多的想法。使用AngularJS后,我不确定是否要绑定到范围(使用“=”)。事实上,我可以通过进行这些更改来使原始的Plunkr工作:

outerInnerApp.directive("outerDirective", function() {
    return {
        restrict: "E",
        scope: {
        //add outerId here
        outerId: "@"
        },
    link: function(scope, element, attrs) {
        //remove scope assignment here
        //scope.outerId = attrs.outerId;
    },
    templateUrl: "outer-template.html"
    };
});
outerInnerApp.directive("innerDirective", function() {
    return {
    restrict: "E",
    scope: {
        //add innerId here
        innerId: "@"
    },
    link: function(scope, element, attrs) {
        //remove scope assignment here
        //scope.innerId = attrs.innerId;
    },
    templateUrl: "inner-template.html"
    };
});

目前我不明白的原因是,为什么之间存在差异,比如

innerId:"@"

并在链接函数中设置范围的值

link: function(scope, element, attrs) {
    scope.innerId = attrs.innerId;
}

当我发现它为什么表现不同时,我会回复。