无法在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之间的区别 。