首页 文章

AngularJS从子控制器访问父作用域

提问于
浏览
359

我用 data-ng-controller="xyzController as vm" 设置了我的控制器

我有一个父/子嵌套控制器的场景 . 通过使用 $parent.vm.property 访问嵌套html中的父属性没有问题,但我无法弄清楚如何从我的子控制器中访问父属性 .

我已经尝试注入$ scope然后使用 $scope.$parent.vm.property ,但这不起作用?

有人可以提供建议吗?

9 回答

  • 1

    也许这是蹩脚的,但你也可以将它们指向一些外部对象:

    var cities = [];
    
    function ParentCtrl() {
        var vm = this;
        vm.cities = cities;
        vm.cities[0] = 'Oakland';
    }
    
    function ChildCtrl($scope) {
        var vm = this;
        vm.cities = cities;
    }
    

    这里的好处是ChildCtrl中的编辑现在传播回父级中的数据 .

  • -1

    如果您的HTML如下所示,您可以执行以下操作:

    <div ng-controller="ParentCtrl">
        <div ng-controller="ChildCtrl">
        </div>
    </div>
    

    然后,您可以按如下方式访问父作用域

    function ParentCtrl($scope) {
        $scope.cities = ["NY", "Amsterdam", "Barcelona"];
    }
    
    function ChildCtrl($scope) {
        $scope.parentcities = $scope.$parent.cities;
    }
    

    如果要从视图中访问父控制器,则必须执行以下操作:

    <div ng-controller="xyzController as vm">
       {{$parent.property}}
    </div>
    

    见jsFiddle:http://jsfiddle.net/2r728/

    Update

    实际上,由于您在父控制器中定义了 cities ,因此子控制器将继承所有范围变量 . 所以理论上你不必打电话 $parent . 上面的例子也可以写成如下:

    function ParentCtrl($scope) {
        $scope.cities = ["NY","Amsterdam","Barcelona"];
    }
    
    function ChildCtrl($scope) {
        $scope.parentCities = $scope.cities;
    }
    

    AngularJS文档使用这种方法,here你可以阅读更多关于 $scope 的信息 .

    Another update

    我认为这是原始海报的更好答案 .

    HTML

    <div ng-app ng-controller="ParentCtrl as pc">
        <div ng-controller="ChildCtrl as cc">
            <pre>{{cc.parentCities | json}}</pre>
            <pre>{{pc.cities | json}}</pre>
        </div>
    </div>
    

    JS

    function ParentCtrl() {
        var vm = this;
        vm.cities = ["NY", "Amsterdam", "Barcelona"];
    }
    
    function ChildCtrl() {
        var vm = this;
        ParentCtrl.apply(vm, arguments); // Inherit parent control
    
        vm.parentCities = vm.cities;
    }
    

    如果使用 controller as 方法,还可以按如下方式访问父作用域

    function ChildCtrl($scope) {
        var vm = this;
        vm.parentCities = $scope.pc.cities; // note pc is a reference to the "ParentCtrl as pc"
    }
    

    如您所见,访问 $scopes 有许多不同的方法 .

    更新了小提琴

    function ParentCtrl() {
        var vm = this;
        vm.cities = ["NY", "Amsterdam", "Barcelona"];
    }
        
    function ChildCtrl($scope) {
        var vm = this;
        ParentCtrl.apply(vm, arguments);
        
        vm.parentCitiesByScope = $scope.pc.cities;
        vm.parentCities = vm.cities;
    }
    
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.20/angular.min.js"></script>
    <div ng-app ng-controller="ParentCtrl as pc">
      <div ng-controller="ChildCtrl as cc">
        <pre>{{cc.parentCities | json}}</pre>
        <pre>{{cc.parentCitiesByScope | json }}</pre>
        <pre>{{pc.cities | json}}</pre>
      </div>
    </div>
    
  • 7

    我刚检查过

    $scope.$parent.someProperty
    

    适合我 .

    它会

    {{$parent.someProperty}}
    

    为了观点 .

  • 0

    当您使用 as 语法(如 ParentController as parentCtrl )来定义控制器,然后在 child controller 中访问父作用域变量时,请使用以下命令:

    var id = $scope.parentCtrl.id;
    

    其中 parentCtrl 是使用 as 语法的父控制器的名称, id 是在同一控制器中定义的变量 .

  • 0

    有时您可能需要直接在子范围内更新父属性 . 例如需要在子控制器更改后保存父控件的日期和时间 . 例如Code in JSFiddle

    HTML

    <div ng-app>
    <div ng-controller="Parent">
        event.date = {{event.date}} 
    event.time = {{event.time}}
    <div ng-controller="Child"> event.date = {{event.date}}
    event.time = {{event.time}}
    <br> event.date: <input ng-model='event.date'><br> event.time: <input ng-model='event.time'><br> </div> </div>

    JS

    function Parent($scope) {
           $scope.event = {
            date: '2014/01/1',
            time: '10:01 AM'
           }
        }
    
        function Child($scope) {
    
        }
    
  • 2

    您还可以绕过范围继承并将事物存储在“全局”范围内 .

    如果应用程序中有一个包含所有其他控制器的主控制器,则可以在全局范围内安装“钩子”:

    function RootCtrl($scope) {
        $scope.root = $scope;
    }
    

    然后在任何子控制器中,您可以使用 $scope.root 访问"global"范围 . 您在此处设置的任何内容都将全局可见 .

    例:

    function RootCtrl($scope) {
      $scope.root = $scope;
    }
    
    function ChildCtrl($scope) {
      $scope.setValue = function() {
        $scope.root.someGlobalVar = 'someVal';
      }
    }
    
    function OtherChildCtrl($scope) {
    }
    
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    
    <div ng-app ng-controller="RootCtrl">
      
      <p ng-controller="ChildCtrl">
        <button ng-click="setValue()">Set someGlobalVar</button>
      </p>
      
      <p ng-controller="OtherChildCtrl">
        someGlobalVar value: {{someGlobalVar}}
      </p>
    
    </div>
    
  • 0

    我相信最近我有类似的窘境

    function parentCtrl() {
       var pc = this; // pc stands for parent control
       pc.foobar = 'SomeVal';
    }
    
    function childCtrl($scope) {
    
       // now how do I get the parent control 'foobar' variable?
       // I used $scope.$parent
    
       var parentFoobarVariableValue = $scope.$parent.pc.foobar;
    
       // that did it
    }
    

    我的设置有点不同,但同样的事情应该仍然可行

  • 45

    从子组件中,您可以使用“require”访问父组件的属性和方法 . 这是一个例子:

    家长:

    .component('myParent', mymodule.MyParentComponent)
    ...
    controllerAs: 'vm',
    ...
    var vm = this;
    vm.parentProperty = 'hello from parent';
    

    儿童:

    require: {
        myParentCtrl: '^myParent'
    },
    controllerAs: 'vm',
    ...
    var vm = this;
    vm.myParentCtrl.parentProperty = 'hello from child';
    
  • 595

    超级容易和工作,但不知道为什么....

    angular.module('testing')
      .directive('details', function () {
            return {
                  templateUrl: 'components/details.template.html',
                  restrict: 'E',                 
                  controller: function ($scope) {
                        $scope.details=$scope.details;  <=== can see the parent details doing this                     
                  }
            };
      });
    

相关问题