You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Angular表单选项切换控制div显示隐藏异常问题求助

解决嵌套div切换显示/隐藏的AngularJS作用域问题

嘿,我太懂你这个头疼的问题了!在嵌套控制器里切换状态时,外层的div死活不跟着变化对吧?其实根源是AngularJS的作用域继承机制在搞鬼。

问题分析

你原来的代码里,父控制器MainCtrl定义了一个布尔类型的toggle变量,然后在子控制器InnerCtrl里尝试修改它。但AngularJS的子作用域对原始类型(字符串、数字、布尔值)会创建一个本地副本,而不是直接修改父作用域的变量。这就导致你在子控制器里改的toggle只是子作用域自己的,父作用域里控制显示隐藏的那个toggle完全没变化,自然另一个div不会隐藏。

解决方案:用对象属性代替原始类型变量

最靠谱的解决办法是把要绑定的变量放到一个对象里,因为对象在作用域继承中是引用传递的,子作用域修改对象的属性会直接同步到父作用域。

修改后的控制器代码:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  // 把toggle包装在一个对象里
  $scope.viewState = {
    toggle: false
  };
});

app.controller('InnerCtrl', function($scope) {
  $scope.switchDiv = function() {
    // 修改对象的属性,会直接影响父作用域的viewState
    $scope.viewState.toggle = !$scope.viewState.toggle;
  };
});

对应的模板代码:

<div ng-controller="MainCtrl">
  <!-- 用viewState.toggle判断显示隐藏 -->
  <div ng-show="!viewState.toggle">
    <div ng-controller="InnerCtrl">
      <button ng-click="switchDiv()">切换到另一个div</button>
    </div>
  </div>
  <div ng-show="viewState.toggle">
    这是要显示的另一个div
    <button ng-click="viewState.toggle = false">切换回去</button>
  </div>
</div>

为什么这个方法有效?

AngularJS的作用域继承基于JavaScript原型链。当你访问子作用域的viewState时,因为子作用域没有这个对象,会向上查找父作用域的viewState,然后修改它的toggle属性——这个修改会直接作用在父作用域的对象上,所以外层的ng-show能实时感知到变化,正确切换div的显示/隐藏。

不推荐的方案:用$parent

虽然你可以在子控制器里直接用$parent.toggle来修改父作用域的变量,但这种写法耦合性太高,一旦控制器嵌套结构变化,代码就会出错,所以不建议使用。

内容的提问来源于stack exchange,提问作者Karthey Sundarem

火山引擎 最新活动