【问题标题】:AngularJS ng-if and scopes [duplicate]AngularJS ng-if和范围[重复]
【发布时间】:2015-08-27 12:34:18
【问题描述】:

我正在尝试了解 ng-if 和范围。据我所知, ng-if 创建了一个新的子范围。这是我的问题:

查看

<input ng-model="someValue1" />
<div ng-if="!someCondition">
    <input ng-model="$parent.someValue2" />
</div>

控制器

$scope.someCondition = true;

if ($scope.someCondition) {
    $scope.someValue2 = $scope.someValue1;        
}

如果 someCondition 设置为 true,那么 someValue2 应该与 someValue1 相同。

我的问题是在这两种情况下(真或假)我都无法访问 someValue2。我怎样才能做到这一点?

【问题讨论】:

  • 在 Angular 中,您绝不能直接修改 $parent 属性值。但是,您可以修改 $parent 属性的属性,否则会破坏继承。做:$parent.someValue.num = 10,不要:$parent.someValue = 10
  • 此声明不以任何方式备份。修改$parent 属性似乎工作得很好。最顶部的“已在此处回答”问题的答案解释了修改 $parent 属性是如何工作的,即使有一些可视化,它清楚地表明它是有效的。一个问题是,当添加更多条件和ng-ifs 或创建其他一些子作用域时,$parents 的链可能会更长,并且代码会中断,这与使用对象时不同。实际上,使用这些对象时甚至不需要$parent,只需使用$scope$scope.someValue.num = 10

标签: angularjs angular-ng-if


【解决方案1】:

是的,ng-if 创建了一个新的子作用域

要查看ng-if 中的模型属性,经验法则是:

请勿将范围用作模型

例如

ng-if='showStuff' //here my scope is model **INCORRECT**
ng-if='someObject.showStuff' // ** CORRECT **

在 ng-model 中使用对象属性 - 然后,即使 ng-if 创建新的子范围,父范围也会有更改。

要查看工作中的 Plunker,请看这里:http://jsfiddle.net/Erk4V/4/

【讨论】:

  • 为什么会这样? $scopesomeObject 都只是对象,对吧?是什么让someObject 与众不同?我打算在我的项目中将其命名为scope,同时拥有$scopescope 似乎相当愚蠢。
  • 我查看了最顶部的“已在此处回答”问题,其答案提供了一些见解:)
【解决方案2】:

ngIf 确实使用原型继承创建了一个新范围。这意味着ngIf 范围的原型对象是其父范围的原型对象。因此,如果在其作用域的ngIf 实例上找不到该属性,它将查看其原型对象链以查找该属性。但是,一旦将属性分配给范围的实例,它将不再查看属性的继承链。这是解释 JS 中使用的原型继承的链接:https://github.com/angular/angular.js/wiki/Understanding-Scopes#javascript-prototypal-inheritance

如何解决:

父控制器:

$scope.data = {someValue: true};

儿童控制器:

$scope.data.someValue = false

因为您没有在其父级范围内隐藏属性,您只是在其父级范围内改变一个对象,这确实会改变父级的数据对象。所以在你的情况下:

<input ng-model="data.someValue1" />
<div ng-if="!data.someCondition">
    <input ng-model="data.someValue2" />
</div>

【讨论】:

  • 我会深入研究,谢谢:)
  • user2734679 你能再给我一个解释吗?具有 someValue 的某些值。不幸的是,我仍然不明白。
  • 这不是角度问题。这是一个javascript的东西。所以这里有一些原型继承的例子。
  • 应该有链接吧?
【解决方案3】:

据我所知,ng-if 纯粹是一个显示级别的语句。在给定特定值的情况下,您可以使用它使某些元素可见/不可见,但我认为它不会创建任何类型的范围。您的 HTML 代码将做的是切换辅助输入的可见性。

如果您想在“someCondition”在 false 和 true 之间变化时将您的值 2 切换为等于值 1,那么您可以将 $watch 与以下内容一起使用:

$scope.$watch(someCondition, function(){
  if (someCondition){
    $scope.someValue1 = $scope.someValue2
  }
})

【讨论】:

  • 感谢您的评论。我的情况也在范围内,所以我认为我不需要看。
  • 没有。 ngIf 与 ngShow、ngHide 的不同之处在于它不只是隐藏 html 元素。它完全摧毁了它。它确实使用原型继承创建了一个新范围。 docs.angularjs.org/api/ng/directive/ngIf
  • @user2734679 好兄弟,谢谢你的链接!我每天都在学习有关 Angular 的新知识:-)
  • 这个答案应该被删除
  • ng-if 有自己的作用域,控制器中的$watch 不会监视它,除非您将它用于具有ng-if 作用域的指令。
猜你喜欢
  • 2015-04-17
  • 2014-02-23
  • 1970-01-01
  • 1970-01-01
  • 2014-02-17
  • 1970-01-01
  • 2012-06-25
  • 1970-01-01
  • 2016-12-24
相关资源
最近更新 更多