使用$ compile作为子指令时的范围错误

时间:2015-05-14 12:21:23

标签: javascript angularjs angularjs-directive

我需要在父指令中有条件地使用child指令。

我使用$compile在父指令的link函数中为子指令编译模板,而child指令有自己的独立范围。

问题是当点击子指令的元素时,在父作用域中调用了child指令的ng-click

这是一个SSCCE:



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

app.directive("parentDirective", function($compile) {
  return {
    restrict: "EA",
    scope: {},
    link: function(scope, element, attrs) {
      element.append('!');
      scope.foo = function() {
        alert('parent foo');
      };
      var childTemplate = "<div child-directive ng-click='foo()'>Child directive</div>";
      element.append($compile(childTemplate)(scope));
    }
  };
});

app.directive("childDirective", function() {
  return {
    restrict: "EA",
    scope: {},
    link: function(scope, element, attrs) {
      scope.foo = function() {
        alert('child foo!');
      };
      element.append('!');
    }
  };
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
<div ng-app="test">
  <div parent-directive>Parent directive</div>
</div>
&#13;
&#13;
&#13;

ng-click=foo()应该从子范围调用foo,但它会调用父foo。如果您点击Child directive! div,则会收到Parent foo提醒。

为什么会这样,我怎样才能让它按预期工作?

2 个答案:

答案 0 :(得分:2)

此问题涉及编译范围模板。

检查此PLUNKER

alert('init parent directive -1');将调用alert('init child directive');,最后调用alert('init parent directive-2');

这意味着在plunker示例的line 20中,父指令链接函数创建child-directive但该指令针对 parent directive scope编译而不是scope of the child directive < / strong>,因此$compile()只能看到parent directive scope内部的任何内容,只能看到child scope

如果你需要附加child scope,那么你必须在child directive内编译它。或者更好地在template中使用templateUrlchild directive

答案 1 :(得分:0)

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

app.directive("parentDirective", function($compile) {
  return {
    restrict: "EA",
    template: "<div ng-click='foo()'>Parent directive!</div>", //You can use templateUrl as well
    scope: {},
    link: function(scope, element, attrs) {
      scope.foo = function() {
        alert('parent foo');
      };
      var childTemplate = "<child-directive/>";
      element.append($compile(childTemplate)(scope));
    }
  };
});

app.directive("childDirective", function() {
  return {
    restrict: "EA",
    template: "<div ng-click='foo()'>Child directive!</div>",
    scope: {},
    link: function(scope, element, attrs) {
      scope.foo = function() {
        alert('child foo!');
      };
    }
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"></script>
<div ng-app="test">
  <parent-directive/>
</div>

试试这个