AngularJS:父范围,指令不更新(带隔离范围内)双向绑定 [英] AngularJS: Parent scope not updated in directive (with isolated scope) two way binding

查看:335
本文介绍了AngularJS:父范围,指令不更新(带隔离范围内)双向绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的code,也可在 http://jsfiddle.net/garukun/u69PT/ <拨弄/ A>

I have the following code, which can also be fiddled on http://jsfiddle.net/garukun/u69PT/.

查看:

<div data-ng-app="testApp">
    <div data-ng-controller="testCtrl">
        <strong>{{pkey}}</strong>
        <span data-test-directive data-parent-item="pkey" 
            data-parent-update="update(pkey)"></span>
    </div>
</div>

JS:

var testApp = angular.module('testApp', []);

testApp.directive('testDirective', function ($timeout) {
    return {
        scope: {
            key: '=parentItem',
            parentUpdate: '&'
        },
        replace: true,
        template: '<div><p>{{key}}</p>' +
            '<button data-ng-click="lock()">Lock</button>' +
            '</div>',
        controller: function ($scope, $element, $attrs) {
            $scope.lock = function () {
                $scope.key = 'D+' + $scope.key;
                console.log('DIR :', $scope.key);

                // Expecting $scope.$parent.pkey to have also been
                // updated before invoking the next line.
                $scope.parentUpdate();
                // $timeout($scope.parentUpdate); // would work.
            };
        }
    };
});

testApp.controller('testCtrl', function ($scope) {
    $scope.pkey = 'golden';
    $scope.update = function (k) {
        // Expecting local variable k, or $scope.pkey to have been
        // updated by calls in the directive's scope.
        console.log('CTRL:', $scope.pkey, k);
        $scope.pkey = 'C+' + k;
        console.log('CTRL:', $scope.pkey);
    };
});

基本上,我建立与分离的范围的指令,其中,我双向从父范围(p键)结合的性质(键),并且还委派的方法(parentUpdate)被称为在父范围的上下文

Basically, I'm setting up the directive with an isolated scope, in which I'm two-way binding a property (key) from the parent scope (pkey), and also delegating a method (parentUpdate) to be called in the context of the parent scope.

现在,在指令中NG-Click事件处理程序中,我想调用parentUpdate方法并在做一些事情。当我调用该方法,我期待已更新了我的父母范围的模式。但在现实中,它不是,这是什么我百思不得其解。

Now, during a ng-click event handler in the directive, I want to invoke the parentUpdate method and do something within. When I'm invoking that method, I'm expecting my parent scope's model to have been updated. But in reality, it is not, and this is what's puzzling me.

这可能是因为缺少一些$消化周期的中间,因为包装与$超时parentUpdate调用将正常工作。

It's probably because of some missing $digest cycles in the middle, since wrapping the parentUpdate call with $timeout would work as expected.

有人能阐明什么遗漏一些轻?或如何正确调用parentUpdate?

Could someone shed some light on what's missing? Or how to properly invoked parentUpdate?

推荐答案

OK,我会采取裂缝在这个...看来你之前所改变着孤立的孩子和家长变量 $摘要周期,其中双向逻辑同步两个。以下是详细信息:

OK, I'm going to take a crack at this one... It seems you're changing both the isolated child AND parent variables before a $digest cycle where the bi-direction logic syncs the two. Here's the details:


  1. 首先你的锁()功能通过点击按钮执行。这将更新隔离 $ scope.key 变量。 注意:这不会的立即的更新父 $ scope.pKey ;这通常发生在下一 $摘要周期,但在这种情况下没有。阅读...

  2. 锁()您正在呼叫 parentUpdate()哪些更新家长的 $ scope.pKey 变量。

  3. 那么 $消化周期执行。当它循环它的方式来更改 $ scope.pKey 正确地检测到父范围。

  4. 变更为 $ scope.pKey 触发手表(),是由双向绑定创建在分离的范围。 <一href=\"https://github.com/angular/angular.js/blob/63c5334c84b7269428c710226764d1f08a36e0d4/src/ng/compile.js#L1035-L1048\">These线是最为关键的。

  5. 手表()被隔离范围,检查是否它是双向绑定值与父级的值同步创建。如果不是(它不是在这种情况下)母公司的值复制到隔离范围的即使隔离示波器的价值也发生了变化,实际上已更改第一个

  1. First your lock() function is executed by clicking on the button. This updates the isolated $scope.key variable. NOTE: This does NOT immediately update the parent $scope.pKey; that would normally happen at the next $digest cycle but does not in this case. Read on...
  2. Within lock() you are calling parentUpdate() which updates the parent's $scope.pKey variable.
  3. THEN the $digest cycle executes. When it loops it's way to the parent scope a change to $scope.pKey is correctly detected.
  4. The change to $scope.pKey triggers a watch() that was created by the bi-directional binding in the isolated scope. These lines are the critical ones..
  5. The watch() created by the isolated scope checks whether it's value for the bi-directional binding is in sync with the parent's value. If it isn't (and it's not in this scenario) the parent's value is copied to the isolated scope even though the isolated scope's value has changed also and in fact was changed first.

MISKO对角数据绑定著名文章描述的好处 $摘要周期的方法。你看到的这里是 $消化的做法有意识的副作用改变coalesence其中,作为源$ C ​​$ C评论说,<一个href=\"https://github.com/angular/angular.js/blob/63c5334c84b7269428c710226764d1f08a36e0d4/src/ng/compile.js#L1041\"><$c$c>parent改变,它有precedence ......这意味着你的隔离范围的变化输了。

Misko's famous post on Angular data-binding describes the benefits of the $digest cycle approach. What you're seeing here is a conscious side-effect of the $digest's approach to change coalesence wherein, as the source code comment says, parent changed and it has precedence... and that means your isolated scope's change loses.

$超时()接近你上面提到的在第一只改变隔离示波器的价值避免了这个问题, $消化周期允许它被复制到父作用域成功,然后调用 parentUpdate()

The $timeout() approach you noted above avoids this issue by changing only the isolated scope's value in the first $digest cycle which allows it to be copied to the parent scope successfully and THEN calling parentUpdate()

$编译文档说:

通常是期望通过一个前pression和到母体范围从分离的范围传递数据,这可以通过使地图的局部变量的名称和值的进入前pression包装FN来完成。例如,如果EX pression是增量(量),那么我们可以通过调用localFn作为localFn({量:22})指定的金额值。

Often it's desirable to pass data from the isolated scope via an expression and to the parent scope, this can be done by passing a map of local variable names and values into the expression wrapper fn. For example, if the expression is increment(amount) then we can specify the amount value by calling the localFn as localFn({amount: 22}).

这意味着,在第2步,你可以在你的价值通过一个对象映射像这样通过对 p键

This means, at step #2 you could pass in your value for pkey via an object map like this:

parentUpdate({pkey: 'D+' + $scope.key })

下面是更新后的提琴: http://jsfiddle.net/KbYcr/

Here's the updated fiddle: http://jsfiddle.net/KbYcr/

这篇关于AngularJS:父范围,指令不更新(带隔离范围内)双向绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆