为什么添加显示/隐藏功能会破坏我的AngularJS代码?

时间:2014-07-14 21:53:47

标签: angularjs

从以下工作小提琴开始:

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;
    }
});

但这完全打破了角色反击。我做错了什么?

3 个答案:

答案 0 :(得分:2)

来自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;
    }
});

答案 1 :(得分:0)

它不起作用的原因是因为范围变量在子范围内分配时的行为方式,而且您的模型没有“&#39;”。在里面。 ng-if创建子范围,因为你的ng模型没有&#39;。&#39;在它中它将分配一个名为&#39; cancelMessage&#39;的范围变量。在子范围内,在“测试”中隐藏范围变量。控制器的范围具有相同的名称 - 只要在textarea中输入文本,就会有效地破坏双向模型绑定。

要解决这个问题,你应该有一个&#39;。&#39;在您的ng模型中:

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

通过使用&#39;。&#39;,angular将首先解析点左边的内容,并找到在&#39; test&#39;中定义的引用。控制器。然后它绑定了测试&#39; &quot; cancelMessage&#39;的属性模型。

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

Infamous Dot in ng-Model (by Design)

Demo Plunker

答案 2 :(得分:0)

如果您参考有关ng-if的AngularJS文档,则说

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

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

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

&#13;
&#13;
<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>
&#13;
&#13;
&#13;