【问题标题】:Angular ngModel binding on first level method of $scopeAngular ngModel 绑定在 $scope 的第一级方法上
【发布时间】:2014-06-06 13:36:19
【问题描述】:

这不完全是一些代码的问题,但更多的是我的理解。所以如果这里不合适,请原谅我..

我正在玩一个分配了 ngModel 的简单复选框:

<input type="checkbox" ng-model="someFlag"/>

我希望这会将复选框的布尔值绑定到 $scope.someFlag(如果控制器和其他一切配置正确)。 是的,它确实有效。但有时我发现这不起作用。案例:当我尝试在 someFlag 更改时(例如在 $watch 中)执行某些操作时,该值并未真正绑定。

但后来我偶然发现一位同事在工作中提到过一次:

使用包装对象

现在这样做没有任何问题:

<input type="checkbox" ng-model="wrapperObject.someFlag"/>

观看 $scope.wrapperObject.someFlag 按预期工作。

现在的问题是:为什么?

【问题讨论】:

标签: javascript angularjs


【解决方案1】:

ngModel 指令被执行时,它会读取属性的ng-model 值(在本例中为"someFlag")并将其保存在它的本地函数范围中(不要与角度$scope 混淆)。但是由于 javascript 中的 boolean 是一个原语,所以不能通过引用传递它,只能通过值传递。这意味着只有$scope.someFlag 的值(truefalse)被复制到ngModel,而不是从ngModel 访问和修改$scope.someFlag 的方式。

当你使用包装对象时,它是通过引用传递的,也就是说,在$scope.wrapperObjectngModel的本地函数范围内都是一样的,因为它在后台指向同一个内存地址。

我不确定这是否足够解释,但是在使用 Angular 中的原始值时,您必须记住按引用传递和按值传递之间的区别,并且当原始值发生更改时,应用程序的其他部分可能不知道这一点.

【讨论】:

  • 这正是我想知道的:但是由于 javascript 中的布尔值是一个原始值,因此您不能通过引用传递它,只能通过值传递。
【解决方案2】:

看看这个取自 Egghead.io 的视频,您的问题已在here 中得到解释。

【讨论】:

    【解决方案3】:

    据我了解,如果复选框被选中,您希望将布尔值传递给控制器​​

    试试这个: 在您的 html 中:

    <input type="checkbox" ng-model="value"
                     ng-true-value="YES" ng-false-value="NO"> <br/>
    

    在您的控制器中:

    $scope.value is gives Boolean value// 
    

    【讨论】:

      【解决方案4】:

      这是因为作用域继承。一个不错的 article 关于 angularjs 范围和继承

      我猜你提到的$watch 逻辑可能是从ng-repeatng-if 内部触发的。请记住 angularjs 为 ng-repeatng-if 内的每个对象创建一个新的范围变量。

      &lt;input type="checkbox" ng-model="someFlag"/&gt; //This is a primitive $scope.someFlag

      <input type="checkbox" ng-model="obj.someFlag"/> //This is an object $scope.obj.someFlag
      

      &lt;div ng-repeat="opt in options"&gt; 这里为 opt 变量创建了一个新的子范围 - $scope.somechild。 因此,如果这里引用了原始变量someFlag,它将被视为$scope.child.someFlag。所以这里的任何更新都不会更新父 $scope.someFlag。 但是如果一个对象obj.someFlag在这里被对象继承引用,编译器将尝试在子$scope.child中找到obj.someFlag,因为它不存在,它将在父$scope中搜索,因为它存在这现在将引用$scope.obj.someFlag 并且这里所做的任何修改都是在实际的父范围内完成的。

      【讨论】:

        【解决方案5】:

        这是 Angular 之父之一 Misko Hevery 的座右铭:“模型中应该永远有一个点”。您可以并且可能应该观看此视频:https://www.youtube.com/watch?v=ZhfUv0spHCY&feature=youtu.be&t=32m51s

        ngModel 是一个执行双向数据绑定的指令。绑定到原语(在本例中为布尔值)将使 setter 将其设置在当前范围内,而不是在可能干扰其他范围的已定义范围上。

        在您的场景中,在父作用域中,我们有您的 $scope.someFlag = true。在 child 范围内,我们会收到您的输入:

        <input type="checkbox" ng-model="someFlag"/>
        

        这最初会起作用,但是一旦用户更改了值,someFlag 将在子作用域上创建,并且绑定将从现在开始读取和写入该值。

        我希望这是,不知何故,清楚。

        请注意,这只发生在双向数据绑定指令中,而不是常规指令,例如 ngDisabledngHide

        【讨论】:

          猜你喜欢
          • 2020-07-07
          • 2017-12-06
          • 2021-06-24
          • 1970-01-01
          • 2019-06-30
          • 2020-09-12
          • 2017-04-29
          • 1970-01-01
          • 2019-10-12
          相关资源
          最近更新 更多