无法获得angularjs中的textarea值

时间:2013-04-29 17:13:23

标签: angularjs angular-ui

这是我的plnkr:http://plnkr.co/edit/n8cRXwIpHJw3jUpL8PX5?p=preview你必须点击一个li元素,表格才会出现。输入随机字符串并点击“添加通知”。

,而不是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);
}

返回'undefined'。我注意到当使用ui-if of angular-ui时这不起作用。任何想法为什么这不起作用?如何解决?

4 个答案:

答案 0 :(得分:93)

你的问题在于ui-if部分。 Angular-ui为该指令中的任何内容创建一个新范围,因此为了访问父范围,您必须执行以下操作:

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

而不是

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

答案 1 :(得分:63)

这个问题发生在我身上,而没有对textarea元素周围的元素使用ng-if指令。虽然Mathew的解决方案是正确的,但原因似乎是另一个。搜索该问题指向这篇文章,所以我决定分享这个。

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

如果您有像

这样的变量
$scope.myText = 'Dummy text';
在您的控制器中

并将其绑定到textarea元素,如此

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

AngularJS将在指令范围内查找该变量。它不存在,因此他走向$ parent。变量出现在那里,文本被插入textarea。更改textarea中的文本时,Angular不会更改父变量。相反,它在指令的范围内创建一个新变量,因此原始变量不会更新。如果你按照Mathew的建议将textarea绑定到父变量,Angular将始终绑定到正确的变量,问题就消失了。

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

希望这会为其他人提出这个问题,并且想一想“WTF,我不是在使用ng-if或任何其他指令!”就像我第一次登陆这里时所做的那样;)

更新:使用controller-as语法

想要在很久之前添加这个,但没有时间去做。这是建筑控制器的现代风格,应该用来代替上面的$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';
});

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

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

这是今天这样做的最有效的方法,因为它解决了嵌套范围的问题,使我们可以计算在某个点上我们有多少层。在使用引用范围的旧方法时,在具有ng-controller指令的元素内使用多个嵌套指令可能会导致类似这样的情况。并且没有人真的想要一整天都这样做!

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

答案 2 :(得分:25)

将textarea绑定到范围变量的属性,而不是直接绑定到范围变量:

控制器:

$scope.notice = {text: ""}

模板:

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

答案 3 :(得分:2)

确实,ui-if会产生问题。 Angular if指令根据表达式销毁并重新创建dom树的部分。这是创建新范围而不是marandus建议的textarea指令。

这是关于ngIf和ngShow之间差异的帖子,它描述了这一点 - what is the difference between ng-if and ng-show/ng-hide