【问题标题】:Cannot get textarea value in angularjs无法在angularjs中获取textarea值
【发布时间】:2013-04-29 17:13:22
【问题描述】:

这是我的 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);
}

返回“未定义”。我注意到在使用 ui-if 的 angular-ui 时这不起作用。任何想法为什么这不起作用?如何解决?

【问题讨论】:

    标签: angularjs angular-ui


    【解决方案1】:

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

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

    代替

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

    【讨论】:

    • 效果很好。坦克你这么多。你能说一下textarea发生这种情况的原因吗?
    【解决方案2】:

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

    如果您查看此处的 AngularJS 文档 https://docs.angularjs.org/api/ng/directive/textarea ,您会看到 Angular 添加了自己的指令 &lt;textarea&gt;,它“覆盖”了默认的 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 或任何其他指令!”就像我第一次登陆这里时所做的那样;)

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

    很久以前就想添加这个,但没时间做。这是构建控制器的现代风格,应该代替上面的$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';
    });
    

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

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

    这是当今执行此类操作的最有效方法,因为它解决了嵌套范围的问题,使我们可以计算在某个点上的深度。在使用旧的引用范围的方式时,在带有 ng-controller 指令的元素内使用多个嵌套指令可能会导致类似的情况。没有人真的愿意整天这样做!

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

    【讨论】:

    • 非常详细的解释!很有用!
    • 救了我的命。谢谢你的解释!
    【解决方案3】:

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

    控制器:

    $scope.notice = {text: ""}
    

    模板:

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

    【讨论】:

    • 这在 Angular 1.5 中对我有用。奇怪的限制,我很确定这曾经可以工作(回到 1.3?)直接绑定到范围变量...
    • 这个解决方案似乎比$parent.notice好!!
    • 您的解决方案有效。有什么直接绑定失败的解释吗?
    • 此解决方案有效。 $parent 的另一个解决方案不起作用。
    • 这是一个更好的解决方案
    【解决方案4】:

    确实是ui-if 造成了问题。 Angular if 指令根据表达式破坏和重新创建 dom 树的部分。这是创建新范围,而不是 marandus 建议的 textarea 指令。

    这里有一篇关于 ngIf 和 ngShow 之间差异的帖子很好地描述了这一点——what is the difference between ng-if and ng-show/ng-hide

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-04
      • 1970-01-01
      • 1970-01-01
      • 2017-09-05
      • 1970-01-01
      • 1970-01-01
      • 2013-03-22
      • 2016-11-21
      相关资源
      最近更新 更多