无法在angularjs中获得textarea值

这里是我的plnkr: http ://plnkr.co/edit/n8cRXwIpHJw3jUpL8PX5?p=preview你必须点击li元素,表单才会出现。 input一个随机string,然后点击“添加通知”。 而不是textarea文本,你会得到未定义的。

标记:

<ul> <li ng-repeat="ticket in tickets" ng-click="select(ticket)"> {{ ticket.text }} </li> </ul> <div ui-if="selectedTicket != null"> <form ng-submit="createNotice(selectedTicket)"> <textarea ng-model="noticeText"></textarea> <button type="submit">add notice</button> </form> </div> 

JS部分:

 $scope.createNotice = function(ticket){ alert($scope.noticeText); } 

返回“未定义”。 我注意到这在使用UI时不起作用,如果是angularUI。 任何想法,为什么这是行不通的? 如何解决它?

你的问题在于ui-if部分。 似乎angular-ui为该指令中的任何内容创build了一个新的范围,所以为了访问父范围,你必须这样做:

 <textarea ng-model="$parent.noticeText"></textarea> 

代替

 <textarea ng-model="noticeText"></textarea> 

这个问题发生在我身上,而对textarea元素周围的元素没有使用ng-if指令。 虽然马修的解决scheme是正确的,但理由似乎是另一回事。 寻找这个问题指向这个职位,所以我决定分享这个。

如果你看看这里的AngularJS文档https://docs.angularjs.org/api/ng/directive/textarea ,你可以看到Angular添加了自己的指令<textarea> ,它“覆盖”了默认的HTML textarea元素。 这是导致整个混乱的新范围。

如果你有一个像

 $scope.myText = 'Dummy text'; 

在你的控制器中,并像这样绑定到textarea元素

 <textarea ng-model="myText"></textarea> 

AngularJS会在指令的范围内寻找这个variables。 它不在那里,因此他走到了父母身边。 该variables存在,文本插入到textarea 。 在更改textarea中的textarea ,Angular不会更改父项的variables。 相反,它会在指令的作用域中创build一个新variables,因此原始variables不会被更新。 如果您将textarea绑定到父variables,如Mathew所build议的那样,Angular将始终绑定到正确的variables,问题就消失了。

 <textarea ng-model="$parent.myText"></textarea> 

希望这会为其他人解决这个问题,并且认为“跆拳道,我不使用ng-if或者其他任何指令!” 就像我第一次在这里降落时那样);

更新:使用控制器作为语法

想要添加这个很久以前,但没有时间去做。 这是build筑控制器的现代风格,应该使用而不是上面的$parent东西。 继续阅读,了解如何为什么

由于AngularJS 1.2有能力直接引用控制器对象,而不是使用$scope对象。 这可以通过在HTML标记中使用这个语法来实现:

 <div ng-controller="MyController as myc"> [...] </div> 

stream行的路由模块(即UI路由器)为其状态提供类似的属性。 对于UI路由器,您可以在状态定义中使用以下内容:

 [...] controller: "MyController", controllerAs: "myc", [...] 

这有助于我们避免嵌套或错误地处理作用域的问题。 上面的例子就是这样构造的。 首先是JavaScript部分。 直截了当地说,你简单的不要使用$scope引用来设置你的文本,只需要使用this将属性直接附加到控制器对象。

 angular.module('myApp').controller('MyController', function () { this.myText = 'Dummy text'; }); 

textarea和controller-as语法的标记如下所示:

 <textarea ng-model="myc.myText"></textarea> 

这是今天做这种事情最有效率的方式,因为它解决了嵌套作用域的问题,使我们能够计算出在某个特定点上的深度。 在使用ng-controller指令的元素内部使用多个嵌套指令时,可能会导致使用旧的引用作用域的方式。 没有人真的想整天这样做!

 <textarea ng-model="$parent.$parent.$parent.$parent.myText"></textarea> 

将textarea绑定到作用域variables的属性,而不是直接作用于作用域variables:

控制器:

 $scope.notice = {text: ""} 

模板:

 <textarea ng-model="notice.text"></textarea> 

这确实是ui-if这就造成了这个问题。 Angular if指令根据expression式销毁并重新创builddom树的某些部分。 这是创build新的范围,而不是marandusbuild议的textarea指令。

这里有一篇关于ngIf和ngShow之间差异的文章,描述了这个问题 – ng-if和ng-show / ng-hide之间的区别 。