简体   繁体   English

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

[英]AngularJS : Modify model of parent scope in a directive with '=xxx' isolate scope?

I have an Angular directive which permit to render an user, and create a link to view the user profile, declared as: 我有一个Angular指令,该指令允许呈现用户,并创建一个链接以查看用户配置文件,声明为:

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

As you can see, I'm trying 2 solutions to be able to visit and load the full user profile: onClickBindTo and onPersonClick 如您所见,我正在尝试2种解决方案,以便能够访问和加载完整的用户个人资料: onClickBindToonPersonClick

I use it like that to render a list of persons + their friends: 我这样使用它来呈现人员及其朋友的列表:

// 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>

On the template, I have a link that is supposed to change an attribute of the controller (called currentProfileUri) 在模板上,我有一个链接,该链接应该更改控制器的属性(称为currentProfileUri)

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

I can see that the controller scope variable currentProfileUri is available in the personTemplate.html because I added a debug input: <input type="text" ng-model="onClickBindTo"/> 我可以看到person模板中提供了控制器作用域变量currentProfileUri ,因为我添加了调试输入: <input type="text" ng-model="onClickBindTo"/>

Unfortunately, when I modify the input value, or when I click on the link, the currentProfileUri of the controller is not updated. 不幸的是,当我修改输入值或单击链接时,不会更新控制器的currentProfileUri Is this normal or am I missing something? 这是正常现象还是我缺少了什么?


With the other method it seems to work fine: 使用另一种方法似乎可以正常工作:

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

So to modify a model of the parent scope, do we need to use parent scope functions? 因此,要修改父范围的模型,是否需要使用父范围函数?


By the way, passing an expression with & , I tried another solution: not using a function declared in the controller scope: 顺便说一句,通过&传递表达式,我尝试了另一种解决方案:不使用在控制器范围内声明的函数:

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

How comes it does not work? 怎么不起作用?


My controller has nothing really fancy: 我的控制器没有任何真正的幻想:

$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;
}

I am new to Angular and read everywhere that using an isolate scope permits a two-way data binding with the parent scope, so I don't understand why my changes are not propagated to the parent scope and my debug statement doesn't fire unless I use the scope function changeCurrentProfileUri 我是Angular的新手,并且到处都读到使用隔离范围允许与父范围进行双向数据绑定,所以我不明白为什么我的更改不会传播到父范围并且调试语句不会触发,除非我使用范围函数changeCurrentProfileUri

Can someone explain me how it works? 有人可以解释一下它是如何工作的吗?

In your example the scopes hierarchy is the following: 在您的示例中,作用域层次结构如下:

controller scope 
    ng-repeat scope
        foaf-person scope

so when you declare two-way binding for 'currentProfileUri' it is actually bound to the scope created by ng-repeat, not by the controller, and when your code changes value of onClickBindTo then angularjs executes 'currentProfileUri = newValue' in the ng-repeat scope. 因此,当您声明“ currentProfileUri”的双向绑定时,它实际上是绑定到ng-repeat创建的作用域,而不是控制器,并且当您的代码更改onClickBindTo的值时,angularjs在ng-exe中执行“ currentProfileUri = newValue”重复范围。

Solution is to use objects instead of primitive values for two-way bindings - in this case scopes inheritance always work in proper way. 解决方案是使用对象而不是原始值进行双向绑定-在这种情况下,作用域继承始终以正确的方式起作用。 I mean something like that: 我的意思是这样的:

// 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>

I've prepared a js-fiddle which illustrates this behavior 我准备了一个js小提琴来说明这种行为

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM