Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用隔离作用域使用嵌套指令调用父控制器的函数_Javascript_Angularjs_Angularjs Directive - Fatal编程技术网

Javascript 使用隔离作用域使用嵌套指令调用父控制器的函数

Javascript 使用隔离作用域使用嵌套指令调用父控制器的函数,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,我有一个treeview指令,试图从父控制器调用函数,但似乎无法调用该函数。我不确定这是否是由于树视图的结构和子元素的嵌套或其他原因造成的 在我的html中,我将指令声明为: <div ng-controller="treeController as vm"> <tree src="myList" filter="doSomething()"></tree> <a ng-click="clicked()"> link</a&g

我有一个treeview指令,试图从父控制器调用函数,但似乎无法调用该函数。我不确定这是否是由于树视图的结构和子元素的嵌套或其他原因造成的

在我的html中,我将指令声明为:

<div ng-controller="treeController as vm">
    <tree src="myList" filter="doSomething()"></tree>
    <a ng-click="clicked()"> link</a>
</div>
在我的指令中,我声明了隔离的作用域,以及参数
filter
(第二个app.directive),我用模型绑定前缀
“&
作为前缀。在模板中,我调用ng click,它应该调用主控制器中的函数doSomething()。然而。。。没有骰子

app.directive('tree', function() {
//builds the tree
    return {
        restrict: 'E', 
        replace: true,
        scope: {
            t: '=src'
        },
        template: '<ul><branch ng-repeat="c in t.children" src="c"></branch></ul>'
    };
});

app.directive('branch', function($compile) {
//directive that builds the children/branches
    return {
        restrict: 'E', 
        replace: true, 
        scope: {
            b: '=src',
            filter: '&'
        },
        template: '<li><input type="checkbox" ng-click="filter()" ng-hide="visible" /><a>{{ b.name }}</a></li>',
        link: function (scope, element, attrs) {

           var has_children = angular.isArray(scope.b.children);
            scope.visible = has_children;
            if (has_children) {
                element.append('<tree src="b"></tree>');

                $compile(element.contents())(scope);
            }

            element.on('click', function(event) {
                event.stopPropagation();

                if (has_children) {
                    element.toggleClass('collapsed');
                }
            });
            //test to call function within directive
            //scope.doSomething = function(b) {
            //    alert('test');
            //}
        }
    };
});
app.directive('tree',function(){
//建树
返回{
限制:'E',
替换:正确,
范围:{
t:'=src'
},
模板:“
    ” }; }); 应用程序指令('branch',函数($compile){ //生成子级/分支的指令 返回{ 限制:'E', 替换:正确, 范围:{ b:'=src',, 筛选器:'&' }, 模板:'
  • 以及工作代码示例

    对我错过的东西有什么建议吗

    现在我只是尝试调用该方法,但是最终我需要将所选项作为参数传递回控制器,但现在我只是想弄清楚为什么控制器中的函数不会被调用

    提前谢谢

    更新: 建议将筛选器的声明从分支移动到tree指令

    我在本地更新了代码,因此tree指令如下所示:

    app.directive('tree', function() {
        return {
            restrict: 'E', 
            replace: true,
            scope: {
                t: '=src',
                filter: '&'
            },
            template: '<ul><branch ng-repeat="c in t.children" src="c"></branch></ul>'
        };
    });
    
    app.directive('tree',function(){
    返回{
    限制:'E',
    替换:正确,
    范围:{
    t:'=src',,
    筛选器:'&'
    },
    模板:“
      ” }; });

      注意:筛选器参数已从辅助指令中删除。输出中没有更改。控制器中的函数仍未调用。

      您的树指令没有筛选器方法。您的分支指令只有该属性

      <div ng-controller="treeController as vm">
          <tree src="myList" filter="doSomething()"></tree>
          <a ng-click="clicked()"> link</a>
      </div>
      
      app.directive('tree', function() {
      //builds the tree
          return {
              restrict: 'E', 
              replace: true,
              scope: {
                  t: '=src',
                  filter: '&'
              },
              template: '<ul><branch ng-repeat="c in t.children" src="c" filter="doSomething()"></branch></ul>'
          };
      });
      
      app.directive('branch', function($compile) {
      //directive that builds the children/branches
          return {
              restrict: 'E', 
              replace: true, 
              scope: {
                  b: '=src',
                  filter: '&'
              },
              template: '<li><input type="checkbox" ng-click="filter()" ng-hide="visible" /><a>{{ b.name }}</a></li>',
              link: function (scope, element, attrs) {
      
                 var has_children = angular.isArray(scope.b.children);
                  scope.visible = has_children;
                  if (has_children) {
                      element.append('<tree src="b"></tree>');
      
                      $compile(element.contents())(scope);
                  }
      
                  element.on('click', function(event) {
                      event.stopPropagation();
      
                      if (has_children) {
                          element.toggleClass('collapsed');
                      }
                  });
                  //test to call function within directive
                  //scope.doSomething = function(b) {
                  //    alert('test');
                  //}
              }
          };
      });
      
      
      链接
      app.directive('tree',function(){
      //建树
      返回{
      限制:'E',
      替换:正确,
      范围:{
      t:'=src',,
      筛选器:'&'
      },
      模板:“
        ” }; }); 应用程序指令('branch',函数($compile){ //生成子级/分支的指令 返回{ 限制:'E', 替换:正确, 范围:{ b:'=src',, 筛选器:'&' }, 模板:“
      • {{b.name}
      • ”, 链接:函数(范围、元素、属性){ var有_children=angular.isArray(scope.b.children); scope.visible=有子项; 如果(有子女){ 元素。追加(“”); $compile(element.contents())(范围); } 元素上('click',函数(事件){ event.stopPropagation(); 如果(有子女){ 元素toggleClass('collapsed'); } }); //在指令内调用函数的测试 //scope.doSomething=功能(b){ //警报(“测试”); //} } }; });
        更新: Sundar的评论让我走上了正确的道路这里是更新的指令对我来说主要的问题是我正在使用嵌套指令,所以嵌套项(正在进行函数调用)已超出控制器的范围来更正包括Sundar的更改,但要使嵌套指令正常工作,我必须显式地将控制器设置为父指令级别。我意识到,如果需要在应用程序的多个区域使用指令,这不是一个好选项。但对我来说,该指令仅在一个位置使用,因此如果有人有任何其他建议或更好的方法,我将不胜感激

        app.directive('tree', function() {
            return {
                restrict: 'E', 
                replace: true,
                scope: {
                    t: '=src',
                    filter: '&'
                },
                controller:'treeController', //explicitly set the controller of the parent directive
                template: '<ul><branch ng-repeat="c in t.children" src="c" filter="doSomething(data)"></branch></ul>'
            };
        });
        
        app.directive('branch', function($compile) {
            return {
                restrict: 'E', 
                replace: true, 
                scope: {
                    b: '=src',
                    filter: '&'
                },
        
                template: '<li><input type="checkbox" ng-click="innerCall()" ng-hide="visible" /><a>{{ b.name }}</a></li>',
                link: function (scope, element, attrs) {
        
                   var has_children = angular.isArray(scope.b.children);
                    scope.visible = has_children;
                    if (has_children) {
                        element.append('<tree src="b"></tree>');
        
                        $compile(element.contents())(scope);
                    }
        
                    element.on('click', function(event) {
                        event.stopPropagation();
        
                        if (has_children) {
                            element.toggleClass('collapsed');
                        }
                    });
                    scope.innerCall = function() {
                        scope.filter(scope.b);
                    }
                }
            };
        });
        
        app.directive('tree',function(){
        返回{
        限制:'E',
        替换:正确,
        范围:{
        t:'=src',,
        筛选器:'&'
        },
        控制器:'treeController',//显式设置父指令的控制器
        模板:“
          ” }; }); 应用程序指令('branch',函数($compile){ 返回{ 限制:'E', 替换:正确, 范围:{ b:'=src',, 筛选器:'&' }, 模板:“
        • {{b.name}
        • ”, 链接:函数(范围、元素、属性){ var有_children=angular.isArray(scope.b.children); scope.visible=有子项; 如果(有子女){ 元素。追加(“”); $compile(element.contents())(范围); } 元素上('click',函数(事件){ event.stopPropagation(); 如果(有子女){ 元素toggleClass('collapsed'); } }); scope.innerCall=函数(){ 范围过滤器(范围b); } } }; });
          您必须在分支指令而不是树中添加筛选器directive@sundar我做了更改并进行了测试,但是控制器中的函数仍然没有被调用,并且没有生成错误。该函数仍然没有被调用。我更新了一个fiddle,修改了建议的代码。但是我仍然看到了相同的结果。
          app.directive('tree', function() {
              return {
                  restrict: 'E', 
                  replace: true,
                  scope: {
                      t: '=src',
                      filter: '&'
                  },
                  controller:'treeController', //explicitly set the controller of the parent directive
                  template: '<ul><branch ng-repeat="c in t.children" src="c" filter="doSomething(data)"></branch></ul>'
              };
          });
          
          app.directive('branch', function($compile) {
              return {
                  restrict: 'E', 
                  replace: true, 
                  scope: {
                      b: '=src',
                      filter: '&'
                  },
          
                  template: '<li><input type="checkbox" ng-click="innerCall()" ng-hide="visible" /><a>{{ b.name }}</a></li>',
                  link: function (scope, element, attrs) {
          
                     var has_children = angular.isArray(scope.b.children);
                      scope.visible = has_children;
                      if (has_children) {
                          element.append('<tree src="b"></tree>');
          
                          $compile(element.contents())(scope);
                      }
          
                      element.on('click', function(event) {
                          event.stopPropagation();
          
                          if (has_children) {
                              element.toggleClass('collapsed');
                          }
                      });
                      scope.innerCall = function() {
                          scope.filter(scope.b);
                      }
                  }
              };
          });