2013-02-27 2 views
9

In meinem rootscope Ich habe eine visible Eigenschaft, die die Sichtbarkeit eines div steuert

app.run(function ($rootScope) { 
    $rootScope.visible = false; 
}); 

Beispiel HTML:

<section ng-controller='oneCtrl'> 
    <button ng-click='toggle()'>toggle</button> 
    <div ng-show='visible'> 
     <button ng-click='toggle()'>&times;</button> 
    </div> 
</section> 

Controller:

var oneCtrl = function($scope){ 
    $scope.toggle = function() { 
     $scope.visible = !$scope.visible; 
    }; 
} 

Der obige Abschnitt funktioniert gut, das Element wird ohne Probleme angezeigt oder ausgeblendet. Jetzt auf der gleichen Seite in einem anderen Abschnitt versuche ich, die visible Variable zu ändern, um das div zu zeigen, aber es funktioniert nicht.

<section ng-controller='otherCtrl'> 
    <button ng-click='showDiv()'>show</button> 
</section> 

Controller:

var otherCtrl = function($scope){ 
    $scope.showDiv = function() { 
     $scope.visible = true; 
    }; 
} 
+0

Haben Sie eine JSFiddle davon können wir sehen? –

+1

Mein aktueller Code ist größer, hier ist nur eine kurze und kurze Version. – olanod

Antwort

22

In AngularJS, $scope s prototypisch erben von ihren übergeordneten Bereich, den ganzen Weg bis zu $rootScope. In JavaScript werden primitive Typen überschrieben, wenn ein Kind sie ändert. Wenn Sie $scope.visible in einem Ihrer Controller festlegen, wurde die Eigenschaft $rootScope nie berührt, sondern eine neue visible-Eigenschaft wurde dem aktuellen Bereich hinzugefügt.

In AngularJS sollten Modellwerte auf dem Oszilloskop immer "einen Punkt haben", also Objekte anstelle von Primitiven sein.

Sie können aber auch Ihren Fall lösen, indem $rootScope Injektion:

var otherCtrl = function($scope, $rootScope){ 
    $scope.showDiv = function() { 
    $rootScope.visible = true; 
    }; 
} 
+0

Ich wollte $ Rootscope nicht in den Controller injizieren, aber es funktioniert. – olanod

+0

Einen Wert in '$ rootScope' zu ​​behalten, ist wahrscheinlich nicht die beste Lösung. Es wird in diesem Fall funktionieren, wie ich schon sagte, aber es ist vielleicht nicht der beste Ansatz. Ohne weitere Informationen ist es jedoch schwer zu sagen, was die beste Lösung wäre. –

1

Wie vertraut sind Sie mit dem Konzept von $ Umfang? Es sieht für mich basierend auf Ihrem Code aus, dass Sie zwei separate $ scope-Variablen namens "visible" in zwei verschiedenen Bereichen verwalten. Hat jeder Ihrer Controller eigene Bereiche? Dies ist oft der Fall. In diesem Fall bearbeiten Sie tatsächlich verschiedene Variablen, die beide "sichtbar" sind, wenn Sie in verschiedenen Controllern ein $ scope.visible = true ausführen.

Wenn das visible wirklich im rootscope ist, können Sie $ rootScope.visible statt $ scope.visible verwenden, aber das ist irgendwie unordentlich.

Eine Option besteht darin, diesen Codeabschnitt "otherCtrl" in einer Direktive zu haben (Sie sollten dies wahrscheinlich trotzdem tun) und dann den Direktivenbereich bidirektional an den übergeordneten Bereich binden, den Sie read up on here. Auf diese Weise verwenden sowohl die Direktive als auch der Seitencontroller das gleiche Scope-Objekt.

Um Ihr $ scope besser zu debuggen, versuchen Sie das Chrome-Plugin für Angular, genannt Batarang. Das bedeutet, dass Sie alle Ihre Bereiche durchqueren und das Modell für Sie entworfen haben, anstatt nur zu hoffen, dass Sie an der richtigen Stelle suchen.

+0

Danke, ich dachte, weil $ rootScope.visible wurde bereits initialisiert $ scope.visible wäre eine Referenz darauf – olanod

+0

Nein! Jeder Controller sollte einen separaten $ scope haben.$ rootScope ist zugänglich, aber sie sind nicht an die Art und Weise gebunden, die Sie beschreiben. Außer wenn Sie in Anweisungen kommen - dann können Sie Eltern/Kind-Scope-Variablen auf die Art und Weise verbinden, wie Sie sie verwenden möchten. Ich würde jedoch immer noch empfehlen, direkt $ rootScope zu verwenden. –

+1

Tatsächlich erben Controller-Bereiche genau wie Direktive-Bereiche bis "$ rootScope". Sie sind * so gebunden wie @olanod es erwartet; Das Problem besteht darin, dass in JavaScript primitive Typen in Children überschrieben werden, wenn die prototypische Vererbung verwendet wird, was $ scope's tun. Aber ich empfehle auch in diesem Fall, $ rootScope zu verwenden - Dienste sind wahrscheinlich die bessere Wahl. –