Alt denetleyiciden AngularJS erişim üst kapsamı


382

Kumandalarımı kullanarak data-ng-controller="xyzController as vm"

Üst / alt iç içe denetleyicileri ile bir senaryo var. Kullanarak iç içe html üst özelliklerine erişmekte sorunum yok $parent.vm.property, ama alt denetleyicisinden üst özelliğine erişmek nasıl anlayamıyorum.

Ben $ kapsamı enjekte ve sonra kullanarak denedim $scope.$parent.vm.property, ama bu çalışmıyor?

Birisi tavsiye verebilir mi?

Yanıtlar:


620

HTML'niz aşağıdaki gibi ise, böyle bir şey yapabilirsiniz:

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

Ardından üst kapsama aşağıdaki gibi erişebilirsiniz

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

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

Bir ebeveyn denetleyiciye görüşünüzden erişmek istiyorsanız, bunun gibi bir şey yapmanız gerekir:

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

Bkz. JsFiddle: http://jsfiddle.net/2r728/

Güncelleme

Aslında citiesüst denetleyicide tanımladığınızdan , alt denetleyiciniz tüm kapsam değişkenlerini devralır. Yani teorik olarak aramak zorunda değilsiniz $parent. Yukarıdaki örnek aşağıdaki gibi de yazılabilir:

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

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

AngularJS belgeleri bu yaklaşımı kullanır, burada hakkında daha fazla bilgi edinebilirsiniz $scope.

Başka bir güncelleme

Bunun orijinal afişe daha iyi bir cevap olduğunu düşünüyorum.

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 asYöntemi kullanırsanız , ana kapsama aşağıdaki gibi de erişebilirsiniz

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

Gördüğünüz gibi erişmenin birçok farklı yolu var $scopes.

Güncellenmiş keman

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
Son güncellemenizle ilgili iki sorunun 1 olduğunu düşünüyorum. Üst kapsamın devralınmasının olası ad alanı çakışmaları olabilir ve 2. Üst denetleyici diğer adının 'pc' olduğu bilgisini gerektirir. Bu, yeniden kullanımı daha zor hale getirir.
tchen

2
Denetleyicileri CtrlName (...) {} işlevi olarak tanımladınız, ancak Açısal adlandırma kullanarak bunu nasıl başarabiliriz? like: angular.module (MdlName) .controller (CtrlName, işlev (...) {});
Pedro Justo

1
Ne demek istiyorsun? Kontrolör sadece bir fonksiyon mu? ieangular.module('app').controller('ParentCtrl', ParentCtrl);
Dieterg

1
üzgünüm, haklısın! 'Controller as' yönteminde, '$ scope.pc.cities;' ebeveynin şehirlerine erişmek bana bir 'geri adım' gibi geliyor çünkü childCtrl'de 'şehirler' özelliğimiz yoksa ebeveynin şehirlerine otomatik olarak erişecektir. Bu sorunu çözmenin başka bir yolu yok mu?
Pedro Justo


46

Yeni kontrol ettim

$scope.$parent.someProperty

benim için çalışıyor.

ve olacak

{{$parent.someProperty}}

görünüm için.


hmmm, benim için çalışmıyor. Denetleyiciyle vm sözdizimi olarak ilgili olup olmadığını merak ediyorum.
zpydee

Üst denetleyiciyi adlandırdıysanız, şablonda $ üst öğe bırakır ve {{vm.someProperty}}
19'da solbs

8

Bir denetleyici tanımlamak için assözdizimini kullanırken , alt denetleyicidekiParentController as parentCtrl üst kapsam değişkenine erişmek için aşağıdakileri kullanın:

var id = $scope.parentCtrl.id;

Burada parentCtrlkullanarak ana kontrolörünün adı assözdizimi ve idaynı kontrolör tanımlanan bir değişkendir.


2

Bazı durumlarda üst özellikleri doğrudan alt kapsam içinde güncellemeniz gerekebilir. çocuk denetleyicisi tarafından yapılan değişikliklerden sonra ana denetimin tarih ve saatini kaydetmeniz gerekir. örn . JSFiddle'daki kod

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

Ayrıca kapsam mirasını atlatabilir ve şeyleri "global" kapsamda saklayabilirsiniz.

Uygulamanızda diğer tüm denetleyicileri saran bir ana denetleyiciniz varsa, genel kapsama bir "kanca" yükleyebilirsiniz:

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

Sonra herhangi bir alt denetleyicide, "global" kapsamına ile erişebilirsiniz $scope.root. Burada ayarladığınız her şey tüm dünyada görünür olacak.

Misal:

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>


Bu gerçekten ölçeklenmiyor. Birçok dosya / bağlamda benzersiz olması gereken global değişkenleri tanımlamak gibidir.
ZachB

Ölçekleme sorunu görmüyorum, ancak kapsam değişkenini 'kök' dışında bir şey çağırmak diğer bağlamlarda daha iyi olabilir
Nico Westerdale

Ayrıca, ihtiyaç duyan bileşen alt ağacının ömründen daha uzun süre asılı kalan bir duruma sahip olmak biraz sıkıntı verici.
Roboprog

0

Son zamanlarda benzer bir problemim olduğuna inanıyorum

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
}

Kurulumum biraz farklıydı, ama aynı şey muhtemelen hala çalışmalı


0

Bir alt bileşenden, üst bileşenin özelliklerine ve yöntemlerine "zorunlu" olarak erişebilirsiniz. İşte bir örnek:

Veli:

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

Çocuk:

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

0

Süper kolay ve çalışıyor, ama neden emin değilim ....

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

Belki de bu topaldır, ancak ikisini de harici bir nesneye yönlendirebilirsiniz:

var cities = [];

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

function ChildCtrl($scope) {
    var vm = this;
    vm.cities = cities;
}

Buradaki fayda, ChildCtrl'deki düzenlemelerin artık üst öğedeki verilere geri yayılmasıdır.


küresel değişkenleri tanıtmak tehlikelidir.
Dementic
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.