为什么范围没有正确地传递给嵌套指令?

时间:2014-04-15 21:55:48

标签: angularjs angularjs-directive

在这个示例plunker http://plnkr.co/edit/k2MGtyFnPwctChihf3M7中,嵌套指令在计算DOM布局时编译良好,但是当指令尝试引用要绑定的变量并且表示变量未定义时出错。为什么会这样?我使用的数据模型是许多嵌套指令的单一模型,因此我希望所有嵌套指令都能够编辑顶级模型。

2 个答案:

答案 0 :(得分:1)

我知道你要做什么的线索。但是,您的注释'所以我希望所有嵌套指令都能够编辑顶级模型'表示您希望您的指令具有控制器的范围。使用

transclude = true
在您的指令中

,以便您的指令可以访问您的父作用域。 http://docs.angularjs.org/guide/directive#creating-a-directive-that-wraps-other-elements

答案 1 :(得分:0)

我不知道你为什么这么做,这似乎应该有一个更好的方法,但这里有一个让你的代码工作的刺激。首先,您创建一个隔离的范围,因此范围不会继承或访问除数据属性中传递的内容之外的任何内容。请注意,您可以将控制器设置为dumbdata = ...并说出<div data="dumbdata",并且您的隔离范围内只有data属性,其中来自父级的dumbdata的值为data财产。我经常尝试为属性和我传递的数据使用不同的名称以避免混淆。

app.directive('project', function($compile) {
  return {
    template: '<div data="data"></div>',
    replace: true,
    scope: {
      data: '=' // problem
    },

接下来,在编译时,您将变量作为范围传递。您需要使用真正的角度范围。一种方法是在指令定义上设置scope: true,这将创建一个新的子范围,但它将从父级继承。

app.directive('outer', function($compile) {
  var r = {
    restrict: 'A',
    scope: true, // new child scope inherits from parent
    compile: function compile(tEle, tAttr) {

更好的方法可能是使用scope.$new()自己创建新的子作用域,然后可以添加新的子属性以传递给后代,避免将值作为作用域传递但仍允许您访问的问题对于您在(plunk)上循环的各个值:

app.directive('outer', function($compile) {
  var r = {
    restrict: 'A',
    compile: function compile(tEle, tAttr) {
      return function postLink(scope,ele,attrs) {
        angular.forEach(scope.outer.middles, function(v, i) {
          var x = angular.element('<div middle></div>');
          var s = scope.$new(); // new child scope
          s.middle = v; // value to be used by child directive
          var y = $compile(x)(s); // compile using real angular scope
          ele.append(y);
        });
      };
    }
  };
  return r;
});