[英]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.