繁体   English   中英

Angular ngClick无法访问其他范围内的变量

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM