【问题标题】:Why does adding a show/hide feature break my AngularJS code?为什么添加显示/隐藏功能会破坏我的 AngularJS 代码?
【发布时间】:2014-10-16 05:31:28
【问题描述】:

从以下工作小提琴开始:

http://jsfiddle.net/77vXu/14/

我添加了一些更改以添加显示/隐藏按钮

http://jsfiddle.net/77vXu/27/

var myApp = angular.module('myApp', []);

myApp.controller('test', function($scope) {
    $scope.show = false;
    $scope.cancelMessage = '';
    $scope.clickTest = function(){
        alert($scope.cancelMessage);
    };
    $scope.toggleShow = function(){
        $scope.show = !$scope.show;
    }
});

但这完全破坏了字符计数器。我做错了什么?

【问题讨论】:

    标签: angularjs


    【解决方案1】:

    来自 angularjs:请注意,当使用 ngIf 删除元素时,它的作用域会被破坏,而当元素恢复时会创建一个新作用域。在 ngIf 中创建的范围使用原型继承从其父范围继承。一个重要的含义是,如果在 ngIf 中使用 ngModel 来绑定到父作用域中定义的 javascript 原语。在这种情况下,对子范围内的变量所做的任何修改都将覆盖(隐藏)父范围内的值。

    解决方案 1。 请从 textarea 中删除 ng-if,请参见此处:http://jsfiddle.net/Tex3P/

    <div ng-app="myApp">
        <div ng-controller="test">
            <button ng-if="!show" ng-click="toggleShow()">show me</button>
            <div ng-if="show">
                <textarea ng-model="cancelMessage" ></textarea>
    <span > {{100 - cancelMessage.length}} characters remaining</span>
    
                <button ng-click="clickTest()" ng-if="show">clickTest</button>
            </div>
        </div>
    </div>
    

    解决方案 2。

    将cancelMessage定义为一个对象。 http://jsfiddle.net/cnre6/

    <div ng-app="myApp">
        <div ng-controller="test">
            <p>f{{cancelMessage}}</p>
            <button ng-if="!show" ng-click="toggleShow()">show me</button>
            <textarea ng-model="cancelMessage" ng-if="show"></textarea>
            <span ng-if="show"> {{100 - cancelMessage.length}} characters remaining</span>
    
            <button ng-click="clickTest()" ng-if="show">clickTest</button>
        </div>
    </div>
    

    var myApp = angular.module('myApp', []);

    myApp.controller('test', function ($scope) {
        $scope.show = false;
        $scope.cancelMessage = {};
        $scope.clickTest = function () {
            alert($scope.cancelMessage);
        };
        $scope.toggleShow = function () {
            $scope.show = !$scope.show;
        }
    });
    

    【讨论】:

      【解决方案2】:

      它不起作用的原因是作用域变量在子作用域内分配时的行为方式,并且您的模型没有“。”在里面。 ng-if 创建一个子范围,因为您的 ng-model 没有“。”在其中,它将在子作用域中分配一个名为“cancelMessage”的作用域变量,该作用域变量在“测试”控制器的作用域中以相同的名称隐藏作用域变量——一旦在文本区域中输入文本,就会有效地破坏双向模型绑定。

      要解决此问题,您应该有一个“。”在你的 ng 模型中:

      <textarea ng-model="cancelMessage.test" ng-if="show"></textarea>
      

      通过使用“.”,angular 将首先解析点的剩余部分,并找到在“测试”控制器中定义的引用。然后它绑定“cancelMessage”模型的“test”属性。

      重要的一点是,绑定正在解析到同一个模型(在“测试”控制器的范围内定义的模型。

      Infamous Dot in ng-Model (by Design)

      Demo Plunker

      【讨论】:

        【解决方案3】:

        如果你参考关于 ng-if 的 AngularJS 文档,它会说

        "ngIf 指令根据 {expression} 删除或重新创建 DOM 树的一部分。如果分配给 ngIf 的表达式的计算结果为 false 值,则该元素将从 DOM 中删除,否则将克隆该元素重新插入 DOM。” (https://docs.angularjs.org/api/ng/directive/ngIf)

        您可以做的一件事是隐藏/显示它,而不是使用 ng-show 或 ng-hide 从 DOM 中删除它

        我在这个小提琴中证明了这一点:http://jsfiddle.net/lookman/0rfz6d1v/

        <div ng-app="myApp">
            <div ng-controller="test">
                <button ng-if="!show" ng-click="toggleShow()">show me</button>
                <div ng-show="show">
                    <textarea ng-model="cancelMessage" ></textarea>
        <span > {{100 - cancelMessage.length}} characters remaining</span>
        
                    <button ng-click="clickTest()">clickTest</button>
                </div>
            </div>
        </div>

        【讨论】:

          猜你喜欢
          • 2017-12-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-02-02
          • 2016-08-16
          • 1970-01-01
          相关资源
          最近更新 更多