Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript AngularJS:指令中未更新父作用域(使用隔离作用域)双向绑定_Javascript_Angularjs_Scope_Directive_Two Way - Fatal编程技术网

Javascript AngularJS:指令中未更新父作用域(使用隔离作用域)双向绑定

Javascript AngularJS:指令中未更新父作用域(使用隔离作用域)双向绑定,javascript,angularjs,scope,directive,two-way,Javascript,Angularjs,Scope,Directive,Two Way,我有下面的代码,也可以修改 视图: {{pkey}} JS: var testApp=angular.module('testApp',[]); testApp.directive('testDirective',函数($timeout){ 返回{ 范围:{ 键:'=parentItem', parentUpdate:“&” }, 替换:正确, 模板:'{{key}}'+ “锁”+ '', 控制器:函数($scope、$element、$attrs){ $scope.lock=函数(){ $

我有下面的代码,也可以修改

视图:


{{pkey}}
JS:

var testApp=angular.module('testApp',[]);
testApp.directive('testDirective',函数($timeout){
返回{
范围:{
键:'=parentItem',
parentUpdate:“&”
},
替换:正确,
模板:'{{key}}

'+ “锁”+ '', 控制器:函数($scope、$element、$attrs){ $scope.lock=函数(){ $scope.key='D++$scope.key; log('DIR:',$scope.key); //预期$scope.$parent.pkey也已被删除 //在调用下一行之前更新。 $scope.parentUpdate(); //$timeout($scope.parentUpdate);//可以工作。 }; } }; }); testApp.controller('testCtrl',函数($scope){ $scope.pkey='golden'; $scope.update=函数(k){ //应使用局部变量k或$scope.pkey //由指令范围内的调用更新。 log('CTRL:',$scope.pkey,k); $scope.pkey='C+'+k; log('CTRL:',$scope.pkey); }; });
基本上,我用一个独立的作用域设置指令,在这个指令中,我从父作用域(pkey)双向绑定一个属性(键),并且还委托一个方法(parentUpdate)在父作用域的上下文中调用

现在,在指令中的ng click事件处理程序中,我想调用parentUpdate方法并在其中执行一些操作。当我调用该方法时,我希望父作用域的模型已经更新。但事实并非如此,这正是让我困惑的地方

这可能是因为中间有一些丢失的摘要周期,因为用$TimeOutin包装PalpUpUPDATE调用会正常工作。


有人能解释一下遗漏了什么吗?或者如何正确调用parentUpdate?

好的,我将尝试一下这个。。。在双向逻辑同步两个变量的
$digest
循环之前,您似乎正在更改独立的子变量和父变量。详情如下:

  • 首先单击按钮执行
    lock()
    函数。这将更新隔离的
    $scope.key
    变量注意:这不会立即更新父级
    $scope.pKey
    ;这通常会在下一个
    $digest
    周期发生,但在本例中不会发生。继续阅读…
  • lock()
    中,您正在调用
    parentUpdate()
    ,它更新父级的
    $scope.pKey
    变量
  • 然后执行
    $digest
    循环。当它循环到父作用域时,将正确检测到对
    $scope.pKey
    的更改
  • $scope.pKey的更改将触发由隔离作用域中的双向绑定创建的
    watch()
    。是最关键的
  • 由隔离作用域创建的
    watch()
    检查双向绑定的值是否与父绑定的值同步。如果不是(在本场景中也不是),则将父级的值复制到隔离作用域,即使隔离作用域的值也已更改,并且实际上是先更改的
  • 介绍
    $digest
    循环方法的优点。您在这里看到的是
    $digest
    改变coalesence方法的一个有意识的副作用,正如源代码注释所说。。。这意味着您的独立作用域的更改将丢失

    上面提到的
    $timeout()
    方法通过在第一个
    $digest
    循环中仅更改隔离作用域的值来避免此问题,该循环允许将其成功复制到父作用域,然后调用
    parentUpdate()

    报告说:

    通常需要通过表达式将数据从隔离范围传递到父范围,这可以通过将局部变量名和值的映射传递到表达式包装器fn来完成。例如,如果表达式是increment(amount),那么我们可以通过调用localFn作为localFn({amount:22})来指定amount值

    这意味着,在步骤#2,您可以通过如下对象映射传入
    pkey
    的值:

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

    下面是更新后的提琴:

    使用
    $scope.$apply()
    而不是
    $scope.$digest()
    也可以使用。这也将触发rootScope上的摘要。

    好的,所以这里有一点目标。。。您想知道为什么
    $scope.key='D++$scope.keylock()
    函数中的code>似乎没有任何效果,对吧?感谢您的解释,它真的很有帮助!虽然我知道这是由于$digest循环的设计。我正在寻找一种方法,使隔离作用域的属性构建在父作用域的属性之上,而不必调用超时函数。在这种情况下,由于我们已经处于摘要周期中,我们不能再调用$digest或$apply。理想情况下,我希望调用evalAsync,但这似乎也不起作用。如果angular的袖子中有一个技巧可以绕过这种设计,那将是非常棒的。我认为这就是这样一个技巧:-)我刚刚用细节更新了我的答案,并使用了一个新的JSFIDLE,其中有一个小小的更改来演示它。
    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);
        };
    });
    
    parentUpdate({pkey: 'D+' + $scope.key })