AngularJS:在'= xxx'隔离范围的指令中修改父范围的模型?

时间:2014-01-02 14:50:48

标签: javascript angularjs angularjs-directive angularjs-scope angularjs-ng-repeat

我有一个允许呈现用户的Angular指令,并创建一个链接来查看用户配置文件,声明为:

.directive('foafPerson', function() {
    return {
      restrict: 'E',
      templateUrl: 'templates/person.html',
      scope: {
        personModel: '=',
        onClickBindTo: '=',
        onPersonClick: '&'
      }
    };

正如您所看到的,我正在尝试两种解决方案,以便能够访问并加载完整的用户个人资料:onClickBindToonPersonClick

我用它来渲染一个人和他们的朋友列表:

// display the current user
<foaf-person person-model="person" on-person-click="changeCurrentProfileUri(person.uri)" on-click-bind-to="currentProfileUri"></foaf-person>

// display his friends
<div class="profileRelationship" ng-repeat="relationship in relationships">
    <foaf-person person-model="relationship" on-person-click="changeCurrentProfileUri(relationship.uri)" on-click-bind-to="currentProfileUri"></foaf-person>
</div>

在模板上,我有一个应该更改控制器属性的链接(名为currentProfileUri)

<a href="" ng-click="onClickBindTo = personModel.uri">
    {{personModel.name}}
<a/>

我可以看到控制器范围变量currentProfileUri在personTemplate.html中可用,因为我添加了一个调试输入:<input type="text" ng-model="onClickBindTo"/>

不幸的是,当我修改输入值或单击链接时,控制器的currentProfileUri未更新。这是正常还是我错过了什么?


使用其他方法似乎工作正常:

<a href="" ng-click="onPersonClick()">
    {{personModel.name}}
<a/>

因此,要修改父作用域的模型,我们是否需要使用父作用域函数?


顺便说一下,用&传递一个表达式,我尝试了另一个解决方案:不使用在控制器范围内声明的函数:

<foaf-person person-model="relationship" on-person-click="currentProfileUri = relationship.uri"></foaf-person>

怎么会不起作用?


我的控制器没什么特别的想法:

$scope.currentProfileUri = 'https://my-profile.eu/people/deiu/card#me';

$scope.$watch('currentProfileUri', function() {
  console.debug("currentProfileUri changed to "+$scope.currentProfileUri);
  loadFullProfile($scope.currentProfileUri);
})

$scope.changeCurrentProfileUri = function changeCurrentProfileUri(uri) {
  console.debug("Change current profile uri called with " + uri);
  $scope.currentProfileUri = uri;
}

我是Angular的新手并且在任何地方都读到使用隔离范围允许与父作用域进行双向数据绑定,所以我不明白为什么我的更改没有传播到父作用域而我的调试语句没有'除非我使用范围函数changeCurrentProfileUri

,否则不会触发

有人可以解释一下它的运作方式吗?

1 个答案:

答案 0 :(得分:0)

在您的示例中,范围层次结构如下:

controller scope 
    ng-repeat scope
        foaf-person scope

所以当你为'currentProfileUri'声明双向绑定时,它实际上绑定到ng-repeat创建的作用域,而不是控制器,当你的代码改变onClickBindTo的值时,angularjs执行'currentProfileUri = newValue'in ng-repeat范围。

解决方案是使用对象而不是原始值进行双向绑定 - 在这种情况下,范围继承始终以正确的方式工作。我的意思是这样的:

// display the current user
<foaf-person person-model="person" on-click-bind-to="currentProfile.uri"></foaf-person>

// display his friends
<div class="profileRelationship" ng-repeat="relationship in relationships">
    <foaf-person person-model="relationship" on-click-bind-to="currentProfile.uri"></foaf-person>
</div>

我准备了a js-fiddle which illustrates this behavior