AngularJS'de üst kapsam değişkenini güncelleyin


113

Biri diğerinin içine sarılmış iki denetleyicim var. Artık alt kapsamın üst kapsamdan özellikleri devraldığını biliyorum, ancak üst kapsam değişkenini güncellemenin bir yolu var mı? Şimdiye kadar bariz bir çözümle karşılaşmadım.

Benim durumumda bir form içinde bir takvim denetleyicim var. Formun gönderildiğinde başlangıç ​​ve bitiş tarihlerine sahip olması için üst kapsamdaki (form olan) başlangıç ​​ve bitiş tarihlerini güncellemek istiyorum.


takvim denetleyicinizin bir yönerge olması gerektiği gibi görünüyor.
Jonah

Yanıtlar:


193

Üst kapsamda bir nesne (ilkel değil) kullanmanız gerekir ve ardından onu doğrudan alt kapsamdan güncelleyebileceksiniz.

Veli:

app.controller('ctrlParent',function($scope){
    $scope.parentprimitive = "someprimitive";
    $scope.parentobj = {};
    $scope.parentobj.parentproperty = "someproperty";
});

Çocuk:

app.controller('ctrlChild',function($scope){
    $scope.parentprimitive = "this will NOT modify the parent"; //new child scope variable
    $scope.parentobj.parentproperty = "this WILL modify the parent";
});

Çalışma demosu : http://jsfiddle.net/sh0ber/xxNxj/

Bkz kapsam nüansları angularjs içinde Prototypal / prototipi miras nedir?


1
Bunu uygulamaya çalıştığımda şu hatayı alıyorum: 'Tanımsız' öğesinin 'ebeveyn özelliği' özelliği ayarlanamıyor '.
Malcr001

Kodunuzu gönderebilir misiniz? Fiddle demosunda çalışıyor. Takvim kontrolünüz izole kapsamı kullanıyorsa, üst kapsamdan devralmaz, bu nedenle değeri direktifin kapsamına aktarmanız gerekir.
Dan

Üzgünüm bu soruyu unuttum. Kabul ettim çünkü sonunda bu cevabın yardımıyla çalışmasını sağlamayı başardım.
Malcr001

CtrlParent div öğesine {{parentobj.parentproperty}} koymanın parentobj nesnesini bildiren ve bu nesneyi ctrlParent kapsamında ayarlayan şey olduğunu anlıyorum. Bu doğru bir varsayım mı ?
Stephane

1
Teşekkürler, bu işe yarıyor! Bunu kesinlikle okumalıyım (prototip miras ve ilkeller). SO bağlantınızdan biraz daha fazlasını açıklayan iyi bir okuma önerebilir misiniz?
jvannistelrooy

116

Bu görevi yapmanın ve $scope.$parentdeğişkeni kullanmamanın bir yolu daha var .

Üst kapsamdaki değeri değiştirmek için bir yöntem hazırlayın ve onu alt kapsamda kullanın. Bunun gibi:

app.controller('ctrlParent',function($scope) {
  $scope.simpleValue = 'x';
  $scope.changeSimpleValue = function(newVal) {
    $scope.simpleValue = newVal;
  };
});

app.controller('ctrlChild',function($scope){
    $scope.changeSimpleValue('y');
});

Aynı zamanda çalışır ve değer değişiklikleri üzerinde size daha fazla kontrol sağlar.

Daha sonra da benzeri hatta HTML yöntemini çağırabilirsiniz: <a ng-click="changeSimpleValue('y')" href="#">click me!</a>.


1
Güzel çözüm! bu işe yarar, çünkü geçerli $ kapsamı içinde bir şey bulunamadığında, Angular $ parent one içinde arar. docs.angularjs.org/guide/scope (bkz. 'Kapsam Hiyerarşileri').
Elo

Bu cevabı beğendim, gereksiz bir nesne oluşturmaya gerek yok.
grimmdude

3
Gelecekteki okuyucular: Bu beşlik yorumların tümü biraz yanlış yönlendirilmiş. Her değişken için ("gereksiz nesneler" olan) iki ayarlayıcı işlevi oluşturmak, hantal ve gereksiz bir kalıtım kümesidir ve Açısal yol değildir. Angular'ın yaratıcısı Misko Hevery, "Ne zaman ng-modeliniz varsa, orada bir yerde bir nokta olması gerekir. Eğer bir noktanız yoksa, yanlış yapıyorsunuz." Misko video @ 29:19
Dan

ControllerAS sözdizimini kullanarak bu çözümü nasıl uygulayabilirim?
niran

6

Bu da işe yarar (ancak bunun en iyi uygulamayı takip edip etmediğinden emin değil)

app.controller('ctrlParent',function($scope) {
    $scope.simpleValue = 'x';
});

app.controller('ctrlChild',function($scope){
    $scope.$parent.simpleValue = 'y';
});

1
Doğru söylüyorsunuz, $ kapsam. $ Parent.value kullanmak çoğu durumda işe yarayacaktır, ancak daha büyük, daha karmaşık projelerde yönetimi zor olabileceğinden, genellikle kapsamlı bir şekilde kullanmak en iyi fikir değildir.
Alex Johnson

4

Bir kapsama ilkel bir öznitelik atadığınızda , bir üst etki alanı aynı ada sahip bir özniteliğe sahip olsa bile , her zaman kapsam için yereldir (muhtemelen anında oluşturulur). Bu bir tasarım kararı ve iyi bir IMHO.

Üst kapsamdaki bazı ilkelleri (ints, booleanlar, dizeler) görünümden değiştirmeniz gerekirse, bu kapsamdaki başka bir nesnenin özniteliği olması gerekir, böylece atama şunları okuyabilir:

<a ng-click="viewData.myAttr = 4">Click me!</a>

ve sırayla:

  1. olsun viewDatao tanımlanan şey kapsamı nesneyi
  2. myAttrözniteliğine 4 atayın .

4

Üst öğede belirtilen değişkenlere erişmek için, alt denetleyicide veya şablon dosyasında $ parent kullanmalıyız

Denetleyicide

$scope.$parent.varaiable_name

Html şablonunda

ng-model="$parent.varaiable_name"
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.