角度指令范围隔离

时间:2015-03-20 01:53:23

标签: angularjs directive

我需要在我的树视图复选框上捕获更改事件(动态填充),但只有第一个元素触发函数“eureka”。有人知道我做错了吗?

我的HTML:

            <div ng-controller="TreeCtrl">

                <tree family="treeFamily" done="eureka()">



                </tree>

            </div>

这是我的控制器:

module.registerController("TreeCtrl", function($scope) {


    $scope.eureka = function () {
        alert("it works!!");
    }


    $scope.treeFamily = {
        name : "Parent",
        children: [{
            name : "Child1",
            checked : true,
            children: [{
                name : "Grandchild1",
                children: []
            },{
                name : "Grandchild2",
                checked : true,
                children: [{
                    name : "GrandGrandchild2",
                    checked : true,
                    children: [] 
                }]
            },{
                name : "Grandchild3",
                checked : false,
                children: []
            }]
        }, {
            name: "Child2",
            checked : true,
            children: []
        }]
    };


});

我的指示:

   module.registerDirective("tree", function($compile) {
        return {
            restrict: "EA",
            scope: {
                ngModel: '=',
                ngChange: '&',
                done: '&',
                family: '=',
            },
            template: 
                '<p>{{ family.name }} <input type="checkbox" value="1" ng-model="family.checked" ng-change="done()"><button ng-click="done()">dsfdsfsd</button></p>'+
                '<ul>' + 
                    '<li ng-repeat="child in family.children">' + 
                        '<tree family="child"></tree>' +
                    '</li>' +
                '</ul>',
            compile: function(tElement, tAttr) {
                var contents = tElement.contents().remove();
                var compiledContents;
                return function(scope, iElement, iAttr) {
                    if(!compiledContents) {
                        compiledContents = $compile(contents);
                    }
                    compiledContents(scope, function(clone, scope) {
                             iElement.append(clone); 
                    });
                };
            }
        };
    });

谢谢!

最好的问候

2 个答案:

答案 0 :(得分:1)

我之前做过这种递归指令的事情......好玩:)。无论如何,您可能希望通过引用传递完成。即。

scope: {
    ngModel: '=',
    ngChange: '&',
    done: '=',
    family: '=',
},

你也必须做一些其他的改变。也就是说,你必须在你的指令范围内定义另一个函数。并且具有代替全局函数的模板引用

$scope.localDone = function(){
     $scope.done()  // this is your ereka function
};

并在您的html传递中通过引用

完成
 <tree family="treeFamily" done="eureka">  // no ()

并在您的指令模板中,而不是调用完成调用localDone

  template: 
            '<p>{{ family.name }} <input type="checkbox" value="1" ng-model="family.checked" ng-change="localDone()"><button ng-click="done()">dsfdsfsd</button></p>'+

我希望这有帮助!

答案 1 :(得分:0)

您可以查看此示例,该示例使用require和split up up指令。

http://jsfiddle.net/KRDEf/

然而,将范围绑定更改为=似乎已解决问题。

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

app.controller("TreeCtrl", function($scope) {


  $scope.eureka = function() {
    alert("it works!!");
  }


  $scope.treeFamily = {
    name: "Parent",
    children: [{
      name: "Child1",
      checked: true,
      children: [{
        name: "Grandchild1",
        children: []
      }, {
        name: "Grandchild2",
        checked: true,
        children: [{
          name: "GrandGrandchild2",
          checked: true,
          children: []
        }]
      }, {
        name: "Grandchild3",
        checked: false,
        children: []
      }]
    }, {
      name: "Child2",
      checked: true,
      children: []
    }]
  };


});

app.directive("tree", function($compile) {
  return {
    restrict: "EA",
    scope: {
      ngModel: '=',
      ngChange: '&',
      done: '=',
      family: '=',
    },
    template: '<p>{{ family.name }} <input type="checkbox" value="1" ng-model="family.checked" ng-change="done()">' +        '<button ng-click="done()">dsfdsfsd</button></p>' +
      '<ul>' +
      '<li ng-repeat="child in family.children">' +
      '<tree family="child"></tree>' +
      '</li>' +
      '</ul>',
    compile: function(tElement, tAttr) {
      var contents = tElement.contents().remove();
      var compiledContents;
      return function(scope, iElement, iAttr) {
        if (!compiledContents) {
          compiledContents = $compile(contents);
        }
        compiledContents(scope, function(clone, scope) {
          iElement.append(clone);
        });
      };
    }
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-controller="TreeCtrl" ng-app="app">

  <tree family="treeFamily" done="eureka()">
  </tree>

</div>