![](/img/trans.png)
[英]AngularJS - ng-include ng-controller and scope not binding
[英]AngularJS : ng-include and ng-controller
我有一個應用程序,我正在構建角度,我有大約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>
我希望每個視圖控制器確定頁腳的狀態以及是否隱藏特定內容。 (下面的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;
這樣做的方式更可取。 但是乞丐不能選擇:)
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
,以減少視圖與控制器之間的混淆。
預期產量:
你誤解了控制器的語法( 參見文檔 )是用來做什么的。 它只是一種在本地作用域上公開特定控制器的方法,以便您可以從模板訪問其屬性。 當您在父模板和頁腳模板中使用someController as vm
時,您不會以某種方式在控制器之間創建連接或類似的東西。 您只是在頁腳范圍內設置vm
屬性,因此當您在頁腳模板中使用它時,您正在訪問頁腳的控制器(並且您已阻止前往父控制器的方式)。
對於您要做的事情,您基本上根本不需要控制器作為語法。 只需將數據正確放在$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());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.