Javascript 访问父对象范围的自定义子指令

Javascript 访问父对象范围的自定义子指令,javascript,angularjs,angularjs-directive,angularjs-scope,Javascript,Angularjs,Angularjs Directive,Angularjs Scope,我的angularJS应用程序中有两个自定义指令。一个扮演父母,另一个扮演孩子。我正试图在child指令内访问父级的作用域。但是我没有得到想要的输出 <div ng-controller="CountryCtrl"> {{myName}} <div ng-controller="StateCtrl"> <state nameofthestate="'Tamilnadu'"> <city nameofthec

我的angularJS应用程序中有两个自定义指令。一个扮演父母,另一个扮演孩子。我正试图在child指令内访问父级的作用域。但是我没有得到想要的输出

<div ng-controller="CountryCtrl">
{{myName}}
    <div ng-controller="StateCtrl">
        <state nameofthestate="'Tamilnadu'">
            <city nameofthecity="'Chennai'"></city>
        </state>
    </div>
</div>
预期产量为

India
** Tamilnadu is inside India
**** Chennai is inside Tamilnadu which is in India

有人能告诉我我做错了什么吗?

这对你有用吗?改编自

没有一种简单的方法可以访问转包内容的父元素,因此我们将父控制器注入子元素以访问其作用域

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

  app.controller("CountryCtrl",function($scope){
      $scope.myName = "India";
  });

  app.controller("StateCtrl",function($scope){
  });

  app.directive("state",function(){return {
      restrict : 'E',
      transclude: true,
      scope : { myName  : '=nameofthestate'},
      template:"**   {{myName}} is inside {{$parent.myName}}<br/><ng-transclude></ng-transclude>",
      controller: function ($scope) {
        this.getName = function () {
          return $scope.myName;
        }
      }
  }});

  app.directive("city",function(){return {
      restrict : 'E',
      require:'^state',
      scope : { myName  : '=nameofthecity'},
      template:"****   {{myName}} is inside {{parentName}} which is in {{$parent.myName }}<br/> ",
      link: function(scope, element, attrs, ctrl) {
        scope.parentName = ctrl.getName();
      }
  }});
var-app=angular.module('myApp',[]);
应用程序控制器(“CountryCtrl”,函数($scope){
$scope.myName=“印度”;
});
app.controller(“StateCtrl”,函数($scope){
});
指令(“状态”,函数(){return{
限制:'E',
是的,
作用域:{myName:'=NameOfState'},
模板:“**{myName}}位于{{$parent.myName}}
”内, 控制器:功能($scope){ this.getName=函数(){ 返回$scope.myName; } } }}); app.directive(“city”,function(){return{ 限制:'E', 要求:“^state”, 作用域:{myName:'=NameOfCity'}, 模板:“***{{myName}}位于{{{parentName}}中的{{parentName}}
”中, 链接:函数(范围、元素、属性、ctrl){ scope.parentName=ctrl.getName(); } }});
城市指令$parent是州指令的一个排除范围

state指令的转移范围是继承的$parent of state指令,它是控制器,因此这就是$parent.MyName=India的原因

transcluded scope的$parent是state指令隔离的scope(scope={}),这就是为什么$parent.$parent.MyName=Tamilnadu(Angular 1.3更新的一部分)

发生的一些细节:

transclude:true-该指令创建一个新的“transcluded”子级 作用域,它通常从父作用域继承。如果 指令还创建一个隔离作用域,即transcluded和 隔离作用域是同级的。每个作用域的$parent属性 引用相同的父范围

Angular v1.3更新:如果指令还创建了隔离范围, 转移的作用域现在是隔离作用域的子级。这个 转移和隔离作用域不再是同级。$parent 转移范围的属性现在引用隔离范围

此外,Matthew的答案对于父子指令通信也是正确的

当AngularJS遇到transclude时,它会克隆之前的HTML 将其替换为模板或templateUrl内容。那么,什么时候呢? 遇到ng transclude时,它会编译转写的内容,但是 将其链接到父范围,而不是 指令。因此,转置的内容仍然可以访问 父控制器及其内容,而指令HTML具有 隔离作用域(或新作用域,视情况而定)


AngularJS启动并运行

查看我的指令的解决方案,它可以与许多部件一起工作。我所做的是删除transclude并要求参数。不必担心脏html,只需观看js,简单如f.:D

    CRM.directive('inputwv', function ($compile) {
    var getTemplate = function(contentType) {
        var template = '';

        switch(contentType) {
                case '3':
                    template = '<input type="number" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index )" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px;width:100px">'
                    break;
                case '0':
                    template = '<input type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index )" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">'
                    break;
                case '1':
                    template = '<input type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index )" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">'
                    break;
                case '2':
                    template = '<textarea class="materialize-textarea teal-text" type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index )" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">'
                    break;
                case '4':
                    template = '<input type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index )" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">'
                    break;
                case '5':
                    template = '<input type="date" class="datepicker" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index )" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px"><script type="text/javascript">$(\'.datepicker\').pickadate({selectMonths: true, selectYears: 15});</script>'
                    break;
                default:
                    template = '<textarea class="materialize-textarea teal-text" type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index )" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">'
            }

        return template;
}

    var linker = function(scope, element, attrs) {
        element.html(getTemplate(attrs.typ)).show();

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

    return {
        restrict: "E",
        link: linker
    };
});
CRM.directive('inputwv',函数($compile){
var getTemplate=函数(contentType){
var模板=“”;
开关(contentType){
案例“3”:
模板=“”
打破
案例“0”:
模板=“”
打破
案例“1”:
模板=“”
打破
案例“2”:
模板=“”
打破
案例“4”:
模板=“”
打破
案例“5”:
template='$(\'.datepicker\').pickadate({selectMonths:true,selectYears:15});'
打破
违约:
模板=“”
}
返回模板;
}
变量链接器=函数(范围、元素、属性){
html(getTemplate(attrs.typ)).show();
$compile(element.contents())(范围);
}
返回{
限制:“E”,
链接:链接器
};
});

对不起,您的小提琴不适合我。您好,这可能会对您有所帮助。它看起来像您想要做的。您可以使用
transclude:'element'
进行自定义转置。构造函数可以在
link:function(作用域、元素、属性、Ctlr、transclude){}
yes中找到。它起作用了。但我接受@kwan245的回答,因为它解释了我犯的错误:)感谢Methewi使用了这种方法,但是在我的例子中,保存名称的变量是一个可能会改变的数组。在这种情况下,视图不会更新,有没有办法处理这种情况?我知道我可以用手表,但我想尽量避免这种情况。我举了一个例子:
  var app = angular.module('myApp', []);

  app.controller("CountryCtrl",function($scope){
      $scope.myName = "India";
  });

  app.controller("StateCtrl",function($scope){
  });

  app.directive("state",function(){return {
      restrict : 'E',
      transclude: true,
      scope : { myName  : '=nameofthestate'},
      template:"**   {{myName}} is inside {{$parent.myName}}<br/><ng-transclude></ng-transclude>",
      controller: function ($scope) {
        this.getName = function () {
          return $scope.myName;
        }
      }
  }});

  app.directive("city",function(){return {
      restrict : 'E',
      require:'^state',
      scope : { myName  : '=nameofthecity'},
      template:"****   {{myName}} is inside {{parentName}} which is in {{$parent.myName }}<br/> ",
      link: function(scope, element, attrs, ctrl) {
        scope.parentName = ctrl.getName();
      }
  }});
    CRM.directive('inputwv', function ($compile) {
    var getTemplate = function(contentType) {
        var template = '';

        switch(contentType) {
                case '3':
                    template = '<input type="number" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index )" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px;width:100px">'
                    break;
                case '0':
                    template = '<input type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index )" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">'
                    break;
                case '1':
                    template = '<input type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index )" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">'
                    break;
                case '2':
                    template = '<textarea class="materialize-textarea teal-text" type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index )" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">'
                    break;
                case '4':
                    template = '<input type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index )" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">'
                    break;
                case '5':
                    template = '<input type="date" class="datepicker" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index )" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px"><script type="text/javascript">$(\'.datepicker\').pickadate({selectMonths: true, selectYears: 15});</script>'
                    break;
                default:
                    template = '<textarea class="materialize-textarea teal-text" type="text" ng-init="inputHide[$parent.$index][$index]=false" ng-blur="inputHide[$parent.$index][$index]=false" ng-Enterd="updateRecord(row[0], $parent.$index)" ng-Enteru="inputHide[$parent.$index][$index]=false" ng-model="row[$index]" ng-change="row[$index]" ng-value="row[$index]" ng-Right-Click="click(element, $index, $parent.$index )" ng-esc="inputHide[$parent.$index][$index]=false" style="cursor:cell;border-bottom:0px">'
            }

        return template;
}

    var linker = function(scope, element, attrs) {
        element.html(getTemplate(attrs.typ)).show();

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

    return {
        restrict: "E",
        link: linker
    };
});