[英]Angular ngClick cannot access variable in a different scope
我對Java語言,尤其是AngularJs完全陌生。 這是我的問題,我需要在ng-repeat中調用ng-click函數以在其中隱藏一些html。
據我了解,問題是因為所有變量(在本例中為變量“ locations”)都在另一個無法訪問的范圍內。 有人可以以最快的方式幫助我解決這個問題嗎?
到目前為止,我幾乎只用角html標簽完成了我的網站(這意味着我實際上不必編寫任何自定義函數),而這絕對是最后一步。
另外,據我了解,每當創建一個新的Angle控制器時,它都有自己的作用域。 在這種情況下,所有調用(除了我遇到問題的調用)都是在沒有初始化任何控制器的情況下進行的,那么如何訪問變量? 是否有類似“默認范圍”的內容? 我知道rootScope對我不起作用。
先感謝您。
<div id="top_nav">
<div id="top_nav_right">
<div id="page_header" ng-show="checked" ng-switch on="page">
</div>
<a href="#" ng-click="checked = ! checked">
</a>
</div>
</div>
<div id="main_sidebar" class="check-element animate-hide" ng-show="checked">
<ul class="menu" ng-show="!locations">
</ul>
<ul class="menu" ng-show="locations">
</ul>
</div>
<div id="sub_sidebar" ng-show="checked" ng-switch on="page">
<div ng-switch-default "check-element animate-hide">
<div id="latest_trips_container">
<div ng-controller="PostsCtrlAjax">
<ul id="latest_trips" ng-controller="MyCtrl">
<li ng-repeat="post in travels">
<div id="trip_details">
<a id="details" href="#/details" ng-click="locations =! locations"></a>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
您將必須圍繞兩個HTML片段創建一個控制器:
<div ng-controller="Ctrl">
<!-- YOUR CODE HERE -->
</div>
控制器將定義locations屬性,但在另一個對象內部 (我們將其viewState
):
app.controller("Ctrl", function($scope) {
$scope.viewState = {
locations: false
};
};
然后綁定到內部locations
:
<ul class="menu" ng-show="!viewState.locations">
</ul>
<ul class="menu" ng-show="viewState.locations">
</ul>
...
<a id="details" href="#/details" ng-click="viewState.locations = !viewState.locations">
這樣做的原因以及$rootScope
為何對您不起作用,是因為范圍是如何通過Javascript的原型繼承來繼承其父級屬性的。 大致且實際上不久:
當您從范圍中讀取一個屬性並且該范圍不包含此屬性時,JS將查看其原型( 大致來說,該范圍的父范圍)。 鏈一直延伸到$rootScope
。 因此,將locations
放在$rootScope
中將成功讀取該屬性。
每當將變量寫入作用域時,無論從何處讀取變量,都會將其直接寫入該作用域。 因此,更改內部作用域中的locations
在外部作用域中不起作用(例如$rootScope
)。
將變量放在對象內將導致讀取對象,該對象解析為正確的范圍,然后將屬性寫入正確的對象。
這就是我最終使用的。 看起來非常簡單,但也許會對初學者也有所幫助。 基本上,這是使值可在不同控制器中訪問的代碼。 如果我理解正確,它與Nikos所建議的相同。
var myApp = angular.module('myApp',[]);
myApp.value('Pages',{page:"My Profile"});
myApp.value('Menu',{show:false});
myApp.value('Menu2',{show2:false});
myApp.controller('MainMenu', function($scope,Menu,Pages) {
$scope.menu = Menu;
$scope.pages = Pages;
});
myApp.controller('MainSidebar', function($scope,Menu,Menu2,Pages) {
$scope.menu = Menu;
$scope.menu2 = Menu2;
$scope.pages = Pages;
});
myApp.controller('SecondSidebar', function($scope,Menu,Menu2,Pages) {
$scope.menu = Menu;
$scope.menu2 = Menu2;
$scope.pages = Pages;
});
myApp.controller('TripsFx', function($scope,Menu2,Pages) {
$scope.menu2 = Menu2;
$scope.pages = Pages;
})
這就是我擁有可訪問的Rootscope所做的工作。
在app.run中設置Rootscope:(不要忘記注入$ rootScope)
var myApp = angular.module('ProGen', []);
myApp.run(function($rootScope) {
//setup Rootscope
$rootScope.locations = false;
})
創建一個具有更改Rootscope的功能的Controller(也注入$ rootscope)
function someCtrl($rootScope, $scope) {
$scope.travels = [
{dest: 'Rome'},
{dest: 'London'}
];
$scope.flipMenu = function() {
$rootScope.locations = !$rootScope.locations;
}
}
因此,這是html:
<html ng-app>
{...}
<body>
<div id="main_sidebar">
<ul class="menu" ng-show="!locations">
<li>x1</li>
<li>x2</li>
<li>x3</li>
<li>x4</li>
</ul>
<ul class="menu" ng-show="locations">
<li>y1</li>
<li>y2</li>
<li>y3</li>
<li>y4</li>
</ul>
</div>
<div ng-click="locations =! locations">Change me (no Controller)</div>
<div ng-controller="someCtrl">
<ul>
<li ng-repeat="post in travels">
<div ng-bind="post.dest" ng-click="flipMenu()"></div>
</li>
</ul>
</div>
</body>
</html>
這就是JS:
var myApp = angular.module('ProGen', []);
myApp.run(function($rootScope) {
//setup Rootscope
$rootScope.locations = false;
})
function someCtrl($rootScope, $scope) {
$scope.travels = [
{dest: 'Rome'},
{dest: 'London'}
];
$scope.flipMenu = function() {
$rootScope.locations = !$rootScope.locations;
}
}
您可以在這里找到工作的Plunker: http ://plnkr.co/edit/ygLlIoE55aI5q8Wkicc5?p=preview
不確定這是否是您想要的。 但我希望它能有所幫助。 (不要因為這樣而對我大喊:這是對Angular Zen的反對:-)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.