【问题标题】:Why ng-if creates so much issue in angularjs为什么 ng-if 在 angularjs 中产生这么多问题
【发布时间】:2015-01-02 19:01:49
【问题描述】:

今天遇到了一个很奇怪的问题,想搞明白为什么会这样
下面是我的html

<div class="partial-container workflow-cont" ng-if="true">
<div class="clearfix mb20">
        <h3 class="heading-text pull-left pointer" ng-click="resetRole()" >{{'Roles' | translate}}</h3>
    </div>
    <div class="inner-container blue-border clearfix relative no-padding" ng-if="true">
        <div class="role-left-nav pull-left">
    .
    .
    .
    Some other html
    .
    .
    .
    <div class="any-or-select pull-none clearfix valign-middle">
    <p>
       <input type="radio" name="choice_p" id="low" ng-model="defineChoice" value="0" >
       <label for="low" class="ng-binding">{{'Absolute' | translate}}</label>
    </p>
    <p>
       <input type="radio" name="choice_p" id="medium" ng-model="defineChoice" value="1" >
       <label for="medium" class="ng-binding">{{'Attributes' | translate}}</label>
    </p>
    <p>
       <input type="radio" name="choice_p" id="high" ng-model="defineChoice" value="2"  >
       <label for="high" class="ng-binding">{{'Rule' | translate}}</label>
    </p>
  </div>

现在,当我单击模型 defineChoice 的单选按钮时,值已成功更改。
但是当我尝试从控制器做同样的事情时 $scope.defineChoice = 0 它的值没有变回来,但是当我从控制器执行 console.log 时,它变为零但没有反映在视图中。

但是当我从任何地方删除 ng-if="true" 时,一切都很好! 这是因为 ng-if 创建了一个子作用域,但如果是这样,那么为什么它在 init 时第一次工作但后来变坏了。

【问题讨论】:

标签: javascript angularjs angularjs-scope


【解决方案1】:

在 Angular 中,模型存在于范围内,模型绑定依赖于涉及原型范围继承的范围解析算法。如果模型绑定解析为同一个模型,无论范围如何,对模型的任何更改都将影响所有绑定。这称为双向模型绑定:对模型的更改会影响视图,对视图的更改会影响模型。

现在,当模型为只读时,双向模型绑定可以正常工作。但在没有的情况下,通常是因为您绑定到原语,使用带有可写控件(即 ngModel 和单选按钮)的 ngModel 并且还涉及一个子范围(即 ngIf);一旦模型被写入,双向模型绑定就会中断。写入模型时,它会在子作用域中创建一个与父作用域中的模型同名的模型。您现在有两个模型副本,它们可以彼此独立运行。

你如何解决这个问题?

将 ngModel 绑定到其对象在范围内的属性 - 不要绑定到范围内的原语。

ng-model="someObj.defineChoice"

有时这也被称为“在你的 ngModel 中总是有一个点”的经验法则,这并不总是必要的,但它是一个很好的指导方针。

someObj 被解析时,它将正确解析正确范围内的引用(通过原型范围继承),然后绑定到该引用的属性。重要的一点是,每个模型绑定都会解析同一个模型,因此双向模型绑定即使在模型被写入时也能正常工作。

【讨论】:

  • 明白了。但我想了解为什么原语没有在新范围内解析,而类似“a.b”的模型在新范围内解析。这是范围解析算法中的错误还是 javascript 中原型范围继承的问题?
  • 它与 javascript 原型范围继承的工作方式有关,与 AngularJS 的范围解析算法无关。这并不是 javascript 中的真正错误,因为 javascript 被设计为长时间以这种方式工作。您可以自己尝试这种行为 - 尝试创建一个调用嵌套函数的函数并尝试从链上更高的函数读取属性,然后尝试写入它。
【解决方案2】:

ng-if 创建一个子作用域,因此 ng-if 中的 ng-model 指令绑定到新作用域。要访问父作用域,请使用ng-model="$parent.defineChoice"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-10-19
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 2013-08-11
    • 2012-08-08
    相关资源
    最近更新 更多