Angular - 改变范围没有得到反映 [英] Angular - Changing scope is not getting reflected
问题描述
这很奇怪,因为它应该非常简单.我会先贴出我的代码,然后再提问:
html -
<div>{{addCustom}}//不会改变<div ng-if="addCustom === false">{{addCustom}}//确实发生了变化<button type="button" class="btn btn-primary btn-icon-text" ng-click="addCustom = true"><span class="icon icon-plus"></span>点击这里按钮>
控制器 -
(function(){'使用严格';angular.module('myApp').controller('myController',['$scope',myController]);功能 myController($scope){$scope.addCustom = false;}})();
所以我只是在我的控制器中引入了一个范围变量 - addCustom - 并将其设置为 false 作为默认值.此变量控制是否显示 div.我还在 2 个不同位置的 html 上输出范围的值.请参阅上文.
但是当我在这个 div 中的 ng-click 中更改它的值时,它的值在第二个位置(div 内)发生变化,而不是第一个(div 外).因此,div 也不会改变状态.
我无法弄清楚这里可能有什么问题.有人可以帮忙吗?
当你有 ng-repeat
、ng-switch
和 ng 时,事情就发生了-if
指令,angular 会为这些元素的放置位置创建子作用域.那些新创建的范围通常是从父范围继承的.
对比 原型继承 是什么意思?
如果您有作用域层次结构,则 parent
作用域属性可在子作用域内访问,前提是这些属性是对象(最初引用的对象被传递给子作用域而不创建新的引用).但是原始数据类型在子范围内不可访问,如果您查看代码,addCustom
范围变量是原始数据类型.
让我们讨论更多.
这里有 myController
控制器,它具有原始类型的 addCustom
范围变量 &正如我上面所说的 ng-switch
&ng-if
指令被编译,它们会在该元素上创建新的子作用域.因此,在您当前的标记中,您在 ng-controller="myController"
div 本身上有 ng-switch
.对于内部 html,它创建了一个子作用域.如果您想访问 child(原始类型)内的父作用域,您可以在作用域变量名称之前使用 $parent
表示法.现在您可以通过 $parent.addCustom
访问 addCustom
值.当 angular 编译器来到 ng-if
div 时,这里还没有结束,它会再次创建新的子作用域.现在 ng-if
的内部容器将再次具有子作用域,该子作用域原型继承自父级.不幸的是,在您的情况下,您有原始 dataType 变量,因此您需要再次使用 $parent
表示法.因此,在 ng-if
div 中,您可以通过执行 $parent.$parent.addCustom
来访问 addCustom
.这个 $parent
的东西会解决你的问题,但是把它放在 HTML 上会使它变得不可读并且与它的父作用域紧密耦合(假设在 UI 上你有 5 个子作用域,那么它看起来像 $parent.$parent.$parent.$parent
).因此,您应该采用以下方法.
在定义ng-model
时遵循Dot rule
所以我会说你需要创建一些像 $scope.model = {}
的对象,并向它添加 addCustom
属性.这样它将遵循原型继承原则,子作用域将使用由父级创建的相同对象.
angular.module('myApp').controller('myController',['$scope',myController]);功能 myController($scope){$scope.model = { addCustom : false };}
在 HTML 上,您将使用 model.addCustom
而不是 addCustom
标记
<div>{{model.addCustom}}//不会改变<div ng-if="model.addCustom === false">{{model.addCustom}}//确实发生了变化<button type="button" class="btn btn-primary btn-icon-text" ng-click="model.addCustom = true"><span class="icon icon-plus"></span>点击这里按钮>