角度指令范围隔离



我需要在树视图复选框上捕获更改事件(动态填充),但只有第一个元素触发函数"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); 
                    });
                };
            }
        };
    });

谢谢!

向致以最诚挚的问候

我以前做过这种递归指令。。。有趣:)。无论如何,您可能希望通过引用传递done。即

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

你还需要做一些其他的改变。也就是说,您必须在指令的作用域中定义另一个函数。并且具有代替全局函数的函数的模板引用

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

并且在您的html通行证中通过引用完成

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

并且在您的指令模板中,而不是调用done call localDone

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

我希望这能有所帮助!

您可以查看这个使用require和split指令的示例。

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>

最新更新