Javascript 角度范围绑定

Javascript 角度范围绑定,javascript,angularjs,angularjs-scope,Javascript,Angularjs,Angularjs Scope,我在看一本书,使用这个版本的Angular: 这是我的模板: <div ng-controller="ParentController"> <div ng-controller="ChildController"> <a ng-click="sayHello()">Say hello</a> </div> {{ person }} </div> 我注意到我的代码没有按预期更新模板,除

我在看一本书,使用这个版本的Angular:

这是我的模板:

<div ng-controller="ParentController">
    <div ng-controller="ChildController">
        <a ng-click="sayHello()">Say hello</a>
    </div>
    {{ person }}
</div>
我注意到我的代码没有按预期更新模板,除非我将sayHello方法更改为:

$scope.sayHello = function () {
    $scope.person.name = "Ari Lerner";
    $scope.person.greeted = true;
};
关于为什么会这样,有什么见解吗?我假设更新的person会反映在DOM中


使用1.4.2会产生相同的结果

考虑到属性的索引可能有所不同,我尝试了以下方法:

$scope.person.name = { greeted: true, name: "Ari Lerner" };
(姓名)


胡乱猜测:在我看来,Angular中的某个对象保留了分配给$scope.person的原始对象,并将$scope.person设置为新对象“丢失”了数据绑定。这是真的吗?

您正在创建一个子作用域,该子作用域通常从其父作用域继承。除非您使用的是隔离作用域(指令),否则就是这种情况


要获得非常好的解释,请参见此处

编辑$scope。来自childController(子作用域)的人员使用$scope。类似这样的$parent

app.controller('ChildController', function ($scope) {
    $scope.sayHello = function () {
        $scope.$parent.person = { name: "Ari Lerner", greeted: true };
    }
});

在AngularJS中,作用域使用来自其父代的原型继承

原型继承基本上意味着,如果JavaScript在子作用域上找不到属性,它将查看父作用域

因此,当您执行
$scope.person.name='Ari Lerner'
时,JavaScript会查看
$scope
,发现它没有
person
属性,然后转到它的父级(父级范围),看到它有
person
属性,并将该属性的
name
属性分配给
'Ari

另一方面,当您执行
$scope.person={…}
时,JavaScript并不关心该属性是否存在-它只是执行赋值,确保您的
$scope
现在具有
person
属性。这里的问题是,您的子作用域的
person
属性现在与父作用域的
person
属性形成阴影,该属性仍然具有其原始值。因此,在父控制器中,
person
从未更改

要进一步阅读,请检查以下答案:


正如其他人所说,这是因为您的范围

例如,如果您想在childScope中创建一个新对象,您可以执行
$scope.someObject={}。
现在,JavaScript不知道它们之间的区别

$scope.someNewObject={}

$scope.person={}

因为您只是将一个新对象分配给您的childscope。 另一种表示法是有效的,因为通过抓取
$scope.person.attribute=…
JavaScript知道person对象已经存在。它开始在您的childscope中查找此对象,在那里找不到它,转到parentscope并在那里找到它并设置属性


总之您要么必须使用
$scope.person.attribute
,要么使用
$scope.$parent.person={}

因为您正在创建子作用域,因此需要点符号。要从childController(子作用域)编辑$scope.person,请使用$scope。$parent这样$scope.$parent.person={name:“Ari Lerner”,helleed:true}@timsmiths这不是一个好的做法。谢谢@Agop,感谢您的反馈@如果不知道书中这个例子的上下文,很难说。例如,它是否试图显示原型继承的缺陷?如果是,那么它做得很好。否则,你可能是对的,考虑到它根本不起作用,这可能只是一个坏例子!)
app.controller('ChildController', function ($scope) {
    $scope.sayHello = function () {
        $scope.$parent.person = { name: "Ari Lerner", greeted: true };
    }
});