为什么ng-if会在angularjs中产生如此多的问题

时间:2015-01-02 09:35:38

标签: javascript angularjs angularjs-scope

今天我遇到了一个非常奇怪的问题,只是试图理解为什么会发生这种情况 以下是我的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 =&#34; true&#34;从各地看,一切都很顺利! 这是因为ng-if会创建一个子范围,但如果是这样的话,那么为什么它在init时第一次工作但后来变坏了。

2 个答案:

答案 0 :(得分:4)

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

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

你如何解决这个问题?

将ngModel绑定到对象在作用域上的属性 - 不要绑定到作用域上的基元。

ng-model="someObj.defineChoice"

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

解析someObj后,它将正确解析右侧作用域上的引用(通过原型作用域继承),然后绑定到该引用的属性。重要的是,每个模型绑定都会解析相同的模型,因此即使写入模型,双向模型绑定也能正常工作。

答案 1 :(得分:3)

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