Angular ngClick не может получить доступ к переменной в другой области

StackOverflow https://stackoverflow.com//questions/21025452

Вопрос

Я совершенно новичок в 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= Предварительный просмотр

Не уверены, если это то, что вы хотели.Но я надеюсь, что это поможет в любом случае. (Не кричите на меня, что это против угловых дзен, поскольку по причинам: -)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top