24

Ich habe eine App, die ich mit eckigen bauen, ich habe etwa 8-10 Ansichten zu bauen. Alle Ansichten haben eine gemeinsame Fußzeile, basierend auf der Ansicht und einer Reihe von Geschäftsregeln muss ich bestimmte Inhalte in der Fußzeile anzeigen/ausblenden.AngularJS: ng-include und ng-controller

So. Ich habe Controller für jede Ansicht und dann eine für die Fußzeile. Ich schließe das allgemeine Fußzeilenlayout mit ng-include ein, wobei der HTML-Code, den ich einschließe, den Footer-Controller im ng-Controller referenziert.

Index.HTML

<body ng-controller="MainCtrl as vm"> 
    <p>Message from Main Controller '{{vm.mainMessage}}'</p> 
    <div ng-include="'commonFooter.html'"></div> 
</body> 

commonFooter.html

<div ng-controller="FooterCtrl as vm"> 
    <p>Message from Footer Controller '{{vm.message}}'</p> 
    <p ng-show="vm.showSomthing">Conditional footer Content</p> 
</div> 

Ich möchte jede Ansichten Controller den Zustand der Fußzeile und ob bestimmte Inhalte verborgen ist oder nicht, um zu bestimmen. (shouldDisplaySomthingInFooter unten)

app.controller('MainCtrl', function($scope) { 
    var vm = this; 
    vm.mainMessage= 'HEELO'; 
    vm.shouldDisplaySomthingInFooter = true; 
    window.console.log('Main scope id: ' + $scope.$id); 
}); 

Dann hatte ich gedacht, dass in der FooterController zurück in die übergeordnete Steuerung erreichen würde und die spezifischen Einstellungen herausziehen/deaktivieren Inhaltsregeln auf der Grundlage der Unternehmen zu ermöglichen.

app.controller('FooterCtrl', function($scope) { 
    var vm = this; 
    vm.message = 'vm footer'; 

    window.console.log('Footer scope id: ' + $scope.$id); 
    window.console.log('Footer parent scope id: ' + $scope.$parent.$id); 
    window.console.log('Footer grandparent scope id: ' + $scope.$parent.$parent.$id); 
    window.console.log('Footer grandparent scope name: ' + $scope.$parent.$parent.mainMessage); 
    window.console.log('Footer grandparent scope condition: ' + $scope.$parent.$parent.shouldDisplaySomthingInFooter); 

    vm.showSomthing = false; //how to pull from parent scope to bind the ng-show to a value set in the parent from within a ng-include? 
}); 

Ich habe dieses Beispiel hier: http://plnkr.co/edit/ucI5Cu4jjPgZNUitY2w0?p=preview

Was ich finde, ist, dass ich, wenn ich in den übergeordneten Bereich erreichen, den Inhalt ziehen es als undefiniert zurück kommt, und ich bin nicht sicher, Warum.

Ich kann sehen, dass die Bereiche auf die Großeltern Ebene verschachtelt werden durch die Bereichs-ID überprüft, ich glaube, das liegt daran, dass die ng-umfasst eine zusätzliche Umfang Schicht unterhalb der Ansicht Bereiche hinzufügt. outout from console in attached example

Extra-Punkte: Wenn ich nicht das $ scope-Objekt verwenden muß und mit der var vm = this; Art und Weise halten kann, es zu tun, die vorzuziehen wäre. Aber Bettler können nicht wählerisch sein :)

app.controller('MainCtrl', function($scope) { 
    var vm = this; 

Vielen Dank im Voraus.

Antwort

28

Wenn Sie den Gültigkeitsbereich außerhalb Controller als vm und Ihre innere Controller als foo, können Sie dann Trenne sie leicht und beziehe dich auf vm mit n der Innencontroller.

Demo

HTML:

<body ng-controller="MainCtrl as vm"> 
    <p>Message from Main Controller '{{vm.mainMessage}}'</p> 
    <div ng-include="'commonFooter.html'"></div> 
</body> 

CommonFooter.html:

<div ng-controller="FooterCtrl as footer"> 
    <p>Message from Footer Controller '{{footer.message}}'</p> 
    <p ng-show="vm.shouldDisplaySomethingInFooter">Conditional footer Content</p> 
</div> 

app.js:

var app = angular.module('plunker', []); 

app.controller('MainCtrl', function() { 
    var self = this; 
    self.mainMessage = 'Hello world'; 
    self.shouldDisplaySomethingInFooter = true; 
}); 

app.controller('FooterCtrl', function() { 
    var self = this; 
    self.message = 'vm footer'; 
}); 

Hinweis: Ich habe Ihren var vm = this in var self = this umbenannt, um Klarheit zu schaffen und die Verwirrung zwischen Ihren Ansichten und Ihren Controllern zu verringern.

Erwarteter Ausgang:

output showing the conditionally hidden\shown items

3

Sie haben missverstanden, was der Controller als Syntax (see documentation) für verwendet wird. Es ist nur eine Möglichkeit, einen bestimmten Controller in Ihrem lokalen Bereich verfügbar zu machen, sodass Sie über eine Vorlage auf seine Eigenschaften zugreifen können. Wenn Sie someController as vm in Ihren Eltern- und Fußzeilenvorlagen verwenden, erstellen Sie nicht irgendwie eine Verbindung zwischen den Controllern oder etwas ähnlichem. Sie legen nur eine vm -Eigenschaft im Footer-Bereich fest. Wenn Sie es also in Ihrer Fußzeilenvorlage verwenden, greifen Sie auf den Controller der Fußzeile zu (und Sie haben den Weg zum übergeordneten Controller blockiert).

Für das, was Sie versuchen, an alles zu tun, müssen Sie im Grunde nicht die Controller als Syntax. Setzen Sie Ihre Daten einfach auf $scope und lassen Sie die Scope-Hierarchie den Rest für Sie erledigen.

In Ihren Eltern-Controller:

$scope.features.rock = true; 
$scope.features.roll = false; 

In der Fußzeile Vorlage

<p ng-show="features.rock">...</p> 
<p ng-show="features.roll">...</p> 

können Sie jetzt auch die features von Ihren anderen Controllern sehen und ändern (wie Geltungsbereich Nachkommen Rahmen der übergeordneten Steuerung sind).

2

ich fummelte mit Ihren Plunker, sondern auch verändert var vm = this;-$scope, also ist er auf zusätzlichen Punkten :-)

versagen ich gegen die Verwendung von $scope.$parent genau aus dem Grunde, dringend raten würde es Ihnen zeigen. Verschiedene Direktiven wie ng-include, ng-show usw. erzeugen ihre eigenen Bereiche.

Sie haben keine Kontrolle, wenn jemand in der Zukunft Ihren HTML-Code ändert und absichtlich oder anderweitig Bereiche hinzufügt.

Ich empfehle die Verwendung von Funktionen, die sich auf Ihrem MainCtrl befinden und auf sie über erbende Bereiche zugreifen.

Plunker

$scope.getShouldShow = function() { 
    return $scope.shouldDisplaySomthingInFooter; 
    }; 
    $scope.setShouldShow = function(val) { 
    $scope.shouldDisplaySomthingInFooter = val; 
    }; 

    $scope.getMainMessage = function() { 
    return $scope.mainMessage; 
    } 

Und nannte sie:

<p ng-show="getShouldShow();">Conditional footer Content</p> 

Und:

window.console.log('Footer grandparent scope name: ' + $scope.getMainMessage()); 
    window.console.log('Footer grandparent scope condition: ' + $scope.getShouldShow());