Angular ngClick не может получить доступ к переменной в другой области
-
21-12-2019 - |
Вопрос
Я совершенно новичок в Javascript и особенно AngularJs.Вот моя проблема: мне нужно вызвать функцию ng-click внутри ng-repeat, чтобы скрыть за ее пределами некоторый HTML-код.
Насколько я понимаю, проблема в том, что все переменные (в данном случае конкретно переменные «местоположения») находятся в другой области, к которой я не могу получить доступ.Может ли кто-нибудь помочь мне кратчайшим путем обойти эту проблему?
На данный момент мне удалось почти закончить свой веб-сайт, используя только угловые html-теги (то есть мне действительно не нужно было писать какие-либо пользовательские функции), и это самая последняя часть.
Кроме того, насколько я понимаю, всякий раз, когда создается новый контроллер в angular, он имеет свою собственную область действия.В этом случае все вызовы (кроме того, с которым у меня возникли проблемы) были выполнены без инициализации какого-либо контроллера, так как же получить доступ к переменным?Есть ли что-то вроде «Области по умолчанию»?Я знаю, что 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>
Контроллер определит свойство location, но внутри другой объект (назовем его 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
).
Помещение переменной внутрь объекта приводит к чтению объекта, который разрешается в правильную область, а затем записи свойства в правильный объект.
Другие советы
Это то, что я оказался.Кажется чрезвычайно простым, но, возможно, это поможет другим, которые также являются новичками.Это в основном код для создания значений, доступных в разных контроллерах.Это так же, как предложил Никос, если я правильно понял это.
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.
Установите rootscope в app.run: (не забудьте ввести $ rootscope)
var myApp = angular.module('ProGen', []);
myApp.run(function($rootScope) {
//setup Rootscope
$rootScope.locations = false;
})
.
Создайте контроллер с функцией, которая меняет rofsscope ($ 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;
}
}
.
Вы найдете рабочее портье здесь: http://plnkr.co/edit/ygllioe55ai5q8wkicc5?P= Предварительный просмотр
Не уверены, если это то, что вы хотели.Но я надеюсь, что это поможет в любом случае. (Не кричите на меня, что это против угловых дзен, поскольку по причинам: -)