私は角度で構築しているアプリを持っています、私は構築するために約8-10のビューを持っています。すべてのビューには、フッター上のコンテンツの一部を条件付きで表示/非表示にする必要があるビューと一連のビジネスルールに基づいて、共有フッターがあります。
そう。ビューごとにコントローラーがあり、フッター用にコントローラーがあります。 ng-includeを使用して一般的なフッターレイアウトをインクルードします。ここでインクルードするhtmlは、ng-controllerのフッターコントローラーを参照します。
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>
各View Controllerでフッターの状態と特定のコンテンツが非表示になっているかどうかを判断する必要があります。 (下記のshouldDisplaySomthingInFooter)
app.controller('MainCtrl', function($scope) {
var vm = this;
vm.mainMessage= 'HEELO';
vm.shouldDisplaySomthingInFooter = true;
window.console.log('Main scope id: ' + $scope.$id);
});
次に、FooterControllerで親コントローラーに戻り、特定の設定を引き出して、ビジネスルールに基づいてコンテンツを有効/無効にすることを意図していました。
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?
});
私はここにこの例を持っています: http://plnkr.co/edit/ucI5Cu4jjPgZNUitY2w0?p=preview
私が見つけているのは、親スコープに到達して、未定義として戻ってくるコンテンツを引き出すために、私はなぜかわからないということです。
Scopeidをチェックすると、スコープが祖父母レベルにネストされていることがわかります。これは、ng-includeがビュースコープの下に追加のスコープレイヤーを追加するためだと考えています。
余分なポイント:$ scopeオブジェクトを使用する必要がなく、var vm = this;
望ましい方法。しかし、be食は選択者にはなれません:)
app.controller('MainCtrl', function($scope) {
var vm = this;
事前にどうもありがとうございました。
外部コントローラーをvm
としてスコープし、内部コントローラーをfoo
としてスコープする場合、それらを簡単に分離し、内部コントローラー内でvmを参照できます。
[〜#〜] 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';
});
注:わかりやすくするため、およびビューとコントローラー間の混乱を減らすために、var vm = this
をvar self = this
に名前変更しました。
期待される出力:
controller as構文( ドキュメントを参照 )の使用目的を誤解しています。これは、ローカルスコープで特定のコントローラーを公開する方法であり、テンプレートからそのプロパティにアクセスできます。親テンプレートとフッターテンプレートの両方でsomeController as vm
を使用する場合、何らかの形でコントローラーまたはそのようなものの間に接続を作成しません。フッターのスコープでvm
プロパティを設定しているだけなので、フッターテンプレートで使用すると、フッターのコントローラーにアクセスします(親コントローラーへのアクセスをブロックしました)。
あなたがやろうとしていることのために、基本的にはcontroller as構文はまったく必要ありません。 $scope
にデータを適切に配置し、残りをスコープ階層に任せるだけです。
親コントローラーで:
$scope.features.rock = true;
$scope.features.roll = false;
フッターテンプレート内
<p ng-show="features.rock">...</p>
<p ng-show="features.roll">...</p>
また、他のコントローラーからfeatures
を表示および変更できます(それらのスコープは親コントローラーのスコープの子孫であるため)。
私はあなたのプランカーをいじりましたが、var vm = this;
を$scope
に変更したので、余分な点で失敗しています:-)
$scope.$parent
の使用は、あなたが示す理由とまったく同じ理由で強くお勧めします。 ng-include
、ng-show
などのさまざまなディレクティブは、独自のスコープを生成します。
将来誰かがあなたのhtmlを変更し、意図的またはその他の方法でスコープを追加するかどうかは制御できません。
MainCtrl
にある関数を使用し、スコープを継承してアクセスすることをお勧めします。
$scope.getShouldShow = function() {
return $scope.shouldDisplaySomthingInFooter;
};
$scope.setShouldShow = function(val) {
$scope.shouldDisplaySomthingInFooter = val;
};
$scope.getMainMessage = function () {
return $scope.mainMessage;
}
そしてそれらを呼び出す:
<p ng-show="getShouldShow();">Conditional footer Content</p>
そして:
window.console.log('Footer grandparent scope name: ' + $scope.getMainMessage());
window.console.log('Footer grandparent scope condition: ' + $scope.getShouldShow());