这个问题发生在我身上,而不是ng-if
在 textarea 元素周围的元素上使用指令。虽然马修的解决方案是正确的,但原因似乎是另一个。搜索那个问题指向这个帖子,所以我决定分享这个。
如果您查看此处的 AngularJS 文档https://docs.angularjs.org/api/ng/directive/textarea,您可以看到 Angular 添加了自己的指令<textarea>
,称为“覆盖”默认 HTMLtextarea
元素。这是导致整个混乱的新范围。
如果你有一个像
$scope.myText = 'Dummy text';
在您的控制器中并将其绑定到这样的textarea
元素
<textarea ng-model="myText"></textarea>
AngularJS 会在指令的范围内寻找那个变量。它不在那里,因此他走到 $parent 那里。变量在那里,文本被插入到textarea
. 更改 中的文本时textarea
,Angular 不会更改父变量。相反,它会在指令的范围内创建一个新变量,因此不会更新原始变量。如果textarea
按照 Mathew 的建议将 绑定到父变量,Angular 将始终绑定到正确的变量,问题就消失了。
<textarea ng-model="$parent.myText"></textarea>
希望这会为其他人解决这个问题并思考“WTF,在我的情况下我没有使用 ng-if 或任何其他指令!” 就像我第一次登陆这里时所做的那样;)
更新:使用控制器作为语法
很久以前就想添加这个,但没时间做。这是构建控制器的现代风格,应该用来代替$parent
上面的东西。继续阅读以了解如何以及为什么。
从 AngularJS 1.2 开始,可以直接引用控制器对象而不是使用该$scope
对象。这可以通过在 HTML 标记中使用以下语法来实现:
<div ng-controller="MyController as myc"> [...] </div>
流行的路由模块(即 UI 路由器)为其状态提供了类似的属性。对于 UI 路由器,您在状态定义中使用以下内容:
[...]
controller: "MyController",
controllerAs: "myc",
[...]
这有助于我们规避嵌套或错误寻址范围的问题。上面的示例将以这种方式构建。首先是 JavaScript 部分。直截了当,您简单地不使用$scope
引用来设置文本,只需使用this
将属性直接附加到控制器对象。
angular.module('myApp').controller('MyController', function () {
this.myText = 'Dummy text';
});
with controller-as 语法的标记textarea
如下所示:
<textarea ng-model="myc.myText"></textarea>
这是当今执行此类操作的最有效方法,因为它解决了嵌套范围的问题,使我们可以计算在某个点上我们有多少层。在使用旧的引用范围的方式时,在带有指令的元素内使用多个嵌套指令ng-controller
可能会导致类似的情况。没有人真的想整天这样做!
<textarea ng-model="$parent.$parent.$parent.$parent.myText"></textarea>