Javascript 父范围变量don';当子控制器修改它们时,不会在视图中更新

Javascript 父范围变量don';当子控制器修改它们时,不会在视图中更新,javascript,angularjs,Javascript,Angularjs,此问题的JSFIDLE可在此处找到: JavaScript(console.log中提供的调试信息) var-app=angular.module('StackOverflow',[]); 函数ParentController($scope){ $scope.parentCounter=5; } 函数ChildController($scope){ $scope.childCounter=$scope.parentCounter; $scope.increaseCounters=函数(){ ++

此问题的JSFIDLE可在此处找到:

JavaScript(
console.log
中提供的调试信息)

var-app=angular.module('StackOverflow',[]);
函数ParentController($scope){
$scope.parentCounter=5;
}
函数ChildController($scope){
$scope.childCounter=$scope.parentCounter;
$scope.increaseCounters=函数(){
++$scope.parentCounter;
++$scope.childCounter;
};
}
在上面的示例中,我在父控制器和子控制器中分别有一个名为
parentCounter
childCounter
的计数器。我还在子控制器中提供了一个名为
increaseCounters()
的函数,它将两个计数器都增加一个

这两个计数器都显示在页面上:


父计数器:{{parentCounter}}
子计数器:{{childCounter}}

问题是AngularJS似乎不更新页面上的
{{parentCounter}}
,而只在调用递增计数器函数时更新
{{childCounter}
。有什么我忽略的吗?

+$scope.parentCounter
创建名为
parentCounter
的子作用域属性,该属性隐藏/隐藏同名的父作用域属性

添加
console.log($scope)添加到increaseCounters()函数以查看它

一种解决方法:
+$scope.$parent.parentCounter


您遇到的问题与JavaScript原型继承的工作方式有关。我建议阅读——它有一些很好的图片,解释在子作用域中创建原语时会发生什么情况。

+$scope.parentCounter
创建名为
parentCounter
的子作用域属性,该属性隐藏/隐藏同名的父作用域属性

添加
console.log($scope)添加到increaseCounters()函数以查看它

一种解决方法:
+$scope.$parent.parentCounter


您遇到的问题与JavaScript原型继承的工作方式有关。我建议阅读——它有一些很好的图片,解释在子作用域中创建原语时会发生什么。

因为子控制器获得父计数器值的副本。如果要增加父控制器计数器值,需要在父控制器上执行一个函数:

function ParentController($scope) {
 $scope.parentCounter = 5;

  $scope.increaseParent = function() {
     ++$scope.parentCounter;
  };
}

function ChildController($scope) {
  $scope.childCounter = $scope.parentCounter;
  $scope.increaseCounters = function() {
    console.log('-------------------------------------');
    console.log('parent before: ' + $scope.parentCounter);
    console.log('child before: ' + $scope.childCounter);
    $scope.increaseParent();
    ++$scope.childCounter;
    console.log('parent after: ' + $scope.parentCounter);
    console.log('child after: ' + $scope.childCounter);
  };
}

因为子控制器获取父计数器值的副本。如果要增加父控制器计数器值,需要在父控制器上执行一个函数:

function ParentController($scope) {
 $scope.parentCounter = 5;

  $scope.increaseParent = function() {
     ++$scope.parentCounter;
  };
}

function ChildController($scope) {
  $scope.childCounter = $scope.parentCounter;
  $scope.increaseCounters = function() {
    console.log('-------------------------------------');
    console.log('parent before: ' + $scope.parentCounter);
    console.log('child before: ' + $scope.childCounter);
    $scope.increaseParent();
    ++$scope.childCounter;
    console.log('parent after: ' + $scope.parentCounter);
    console.log('child after: ' + $scope.childCounter);
  };
}

你说得对-在这种情况下,使用
$scope.$parent.parentCounter可以使它正常工作-。@Trevor,我添加了一个链接到我的答案,这应该会很有帮助。使用$scope.$parent.parentCounter的一个缺点是,当你移动父对象或在两者之间放置另一个控制器时,它会崩溃。@asgoth,谢谢,我很懒。我应该提到所有3种选择(我在你的回答中添加了一条关于第三种方法的注释)。你是对的-在本例中,使用
$scope.$parent.parentCounter使其正常工作-。@Trevor,我在我的答案中添加了一个链接,该链接应该会有所帮助。使用$scope.$parent.parentCounter的一个缺点是,当您移动父对象或将另一个控制器放置在两者之间时,它会断开。@asgoth,谢谢,我太懒了。我应该提到所有3种选择(我在你的回答中添加了一条关于第三种方法的注释)。为了完整起见,还有一种选择:在父范围中使用对象。例如,
$scope.someObj={parentCounter:5}
然后在increaseCounters()中,
+$scope.someObj.parentCounter
。由于原型继承,当子作用域查找$scope.someObj时,它将在父作用域中找到它,然后修改parentCounter属性。(我提供的链接中也解释了这一点。)为了完整性,还有一种选择:在父范围中使用对象。例如,
$scope.someObj={parentCounter:5}
然后在increaseCounters()中,
+$scope.someObj.parentCounter
。由于原型继承,当子作用域查找$scope.someObj时,它将在父作用域中找到它,然后修改parentCounter属性。(我提供的链接中也解释了这一点。)