자식 컨트롤러에서 AngularJS 액세스 부모 범위


382

컨트롤러를 사용하여 컨트롤러를 설정했습니다. data-ng-controller="xyzController as vm"

부모 / 자식 중첩 컨트롤러에 대한 시나리오가 있습니다. 을 사용하여 중첩 된 HTML의 부모 속성에 액세스하는 데 문제가 없지만 $parent.vm.property자식 컨트롤러 내에서 부모 속성에 액세스하는 방법을 알 수 없습니다.

$ scope를 주입하고을 사용하려고 시도했지만 $scope.$parent.vm.property작동하지 않습니까?

누구든지 조언을 줄 수 있습니까?

답변:


620

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/

최신 정보

실제로 cities상위 컨트롤러에서 정의한 이후 하위 컨트롤러는 모든 범위 변수를 상속합니다. 이론적으로는 전화 할 필요가 없습니다 $parent. 위의 예제는 다음과 같이 작성할 수도 있습니다.

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

function ChildCtrl($scope) {
    $scope.parentCities = $scope.cities;
}

AngularJS 문서는이 접근법을 사용합니다. 여기에서 에 대해 자세히 읽을 수 있습니다 $scope.

다른 업데이트

나는 이것이 원래 포스터에 대한 더 나은 대답이라고 생각합니다.

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>


6
마지막 업데이트의 두 가지 문제는 1이라고 생각합니다. 부모 범위를 상속하면 잠재적 인 네임 스페이스 충돌이 발생할 수 있으며 2. 부모 컨트롤러 별칭이 'pc'라는 지식이 필요합니다. 이로 인해 재사용이 더 어려워집니다.
tchen

2
컨트롤러를 CtrlName (...) {} 함수로 정의했지만 Angular 명명법을 사용하여 어떻게 달성 할 수 있습니까? : angular.module (MdlName) .controller (CtrlName, function (...) {});
Pedro Justo

1
무슨 소리 야? 컨트롤러는 기능일까요? 즉angular.module('app').controller('ParentCtrl', ParentCtrl);
Dieterg

1
미안, 네 말이 맞아! '$ scope.pc.cities;'를 사용하여 'Controller as'방법에서 childCtrl에 속성 '도시'가 없으면 부모 도시에 자동으로 액세스하기 때문에 부모의 도시에 액세스하는 것은 나에게 '뒤로'인 것 같습니다. 이 문제를 해결할 다른 방법이 없습니까?
Pedro Justo

1
그의는 JavaScript다음을 참조하십시오 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
Dieterg

46

방금 확인했습니다

$scope.$parent.someProperty

나를 위해 작동합니다.

그리고 그것은

{{$parent.someProperty}}

보기를 위해.


흠, 나를 위해 일하지 않습니다. 컨트롤러와 vm 구문과 관련이 있는지 궁금합니다.
zpydee

상위 컨트롤러의 이름을 지정한 경우 템플릿에 $ parent를 삭제하고 {{vm.someProperty}}
solbs

8

당신이 사용하는 경우 as구문을, 같은 ParentController as parentCtrl에서 액세스 부모 범위 변수에 다음 컨트롤러를 정의하는 자식 컨트롤러 사용 다음 :

var id = $scope.parentCtrl.id;

여기서 parentCtrl사용 상위 컨트롤러의 이름 as구문과 id같은 제어기에 정의 된 변수이다.


2

때로는 하위 범위 내에서 직접 상위 속성을 업데이트해야 할 수도 있습니다. 예를 들어 자식 컨트롤러가 변경 한 후 부모 컨트롤의 날짜와 시간을 저장해야합니다. 예 : JSFiddle의 코드

HTML

<div ng-app>
<div ng-controller="Parent">
    event.date = {{event.date}} <br/>
    event.time = {{event.time}} <br/>
    <div ng-controller="Child">
        event.date = {{event.date}}<br/>
        event.time = {{event.time}}<br/>
        <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) {

    }

1

범위 상속을 피하고 "전역"범위에 항목을 저장할 수도 있습니다.

응용 프로그램에 다른 모든 컨트롤러를 래핑하는 기본 컨트롤러가있는 경우 전역 범위에 "후크"를 설치할 수 있습니다.

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

그런 다음 모든 하위 컨트롤러에서을 사용하여 "전역"범위에 액세스 할 수 있습니다 $scope.root. 여기에서 설정 한 모든 것이 전세계에 표시됩니다.

예:

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>


이것은 실제로 확장되지 않습니다. 많은 파일 / 컨텍스트에서 고유해야하는 전역 변수를 정의하는 것과 같습니다.
ZachB

스케일링 문제는 보이지 않지만 스코프 변수를 'root'이외의 것으로 호출하는 것이 다른 상황에서는 더 좋습니다.
Nico Westerdale

또한 상태를 필요로하는 구성 요소 서브 트리의 수명보다 오래 걸려있는 상태를 갖는 것은 약간의 성가신 일입니다.
Roboprog

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
}

내 설정이 약간 다르지만 여전히 같은 일이 작동해야합니다.


0

자식 구성 요소에서 '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';

0

매우 쉽고 효과적이지만 왜 그런지 확실하지 않습니다 ....

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                     
              }
        };
  });

-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의 편집 내용이 이제 부모의 데이터로 다시 전파된다는 이점이 있습니다.


전역 변수를 도입하는 것은 위험합니다.
치매
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.