Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.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
AngularJS-访问子作用域_Angularjs - Fatal编程技术网

AngularJS-访问子作用域

AngularJS-访问子作用域,angularjs,Angularjs,如果我有以下控制器: function parent($scope, service) { $scope.a = 'foo'; $scope.save = function() { service.save({ a: $scope.a, b: $scope.b }); } } function child($scope) { $scope.b = 'bar'; } 让父母从孩

如果我有以下控制器:

function parent($scope, service) {
    $scope.a = 'foo';

    $scope.save = function() {
        service.save({
            a:  $scope.a,
            b:  $scope.b
        });
    }
}

function child($scope) {
    $scope.b = 'bar';
}
让父母从孩子身上读取
b
的正确方法是什么?如果有必要在
parent
中定义
b
,那么假设
b
是一个描述与
child
而不是
parent
相关的内容的属性,这在语义上难道不正确吗


更新:进一步考虑,如果有多个孩子有
b
,则会为要检索的
b
父母产生冲突。我的问题仍然是,从父级访问
b
的正确方法是什么?

AngularJS中的作用域使用原型继承,当在子级作用域中查找属性时,解释器将查找从子级开始的原型链,并继续查找父级,直到找到属性,而不是相反

查看Vojta对该问题的评论

简而言之:您不能从父作用域访问子作用域

您的解决方案:

  • 在父级中定义属性并从子级访问它们(阅读上面的链接)
  • 使用服务共享状态
  • 通过事件传递数据
    $emit
    向上发送事件到父级,直到根作用域和
    $broadcast
    向下发送事件。这可能会帮助您保持语义正确

  • 虽然jm-的答案是处理这种情况的最佳方法,但为了将来参考,可以使用作用域的$$childHead、$$childTail、$$nextSibling和$$Previsibling成员访问子作用域。这些都没有文档记录,所以它们可能会在没有通知的情况下更改,但是如果您真的需要遍历范围,它们就在那里

    //首先获取$$childHead,然后迭代该范围的$$nextSiblings
    对于(var cs=scope.$$childHead;cs;cs=cs.$$nextSibling){
    //cs是子范围
    }
    
    您可以尝试以下方法:

    $scope.child = {} //declare it in parent controller (scope)
    
    然后在子控制器(作用域)中添加:


    现在父控制器可以访问子控制器的作用域。

    一种可能的解决方法是使用init函数将子控制器注入父控制器

    可能的实施方式:

    因此,现在在
    ParentController
    中,您可以使用:

    重要提示:
    要正常工作,您必须使用指令
    ng controller
    ,并使用
    将每个控制器重命名为
    ,就像我在html eg中所做的那样

    提示:

    在此过程中使用chrome插件。它将帮助您理解树。

    是的,我们可以将子控制器中的变量分配给父控制器中的变量。这是一种可能的方法:

    概述:下面代码的主要目的是将子控制器的$scope.variable分配给父控制器的$scope.assign

    说明:有两个控制器。在html中,请注意父控制器包含子控制器。这意味着父控制器将在子控制器之前执行。因此,首先将定义setValue(),然后该控件将转到子控制器$scope.variable将被指定为“child”。然后,此子作用域将作为参数传递给父控制器的函数,其中$scope.assign将获得值为“child”

    
    var-app=angular.module('myApp',[]);
    应用程序控制器('子',函数($范围){
    $scope.variable=“child”;
    $scope.$parent.setValue($scope);
    });
    应用程序控制器('父',功能($范围){
    $scope.setValue=函数(childscope){
    $scope.assign=childscope.variable;
    }
    });
    这是父项:{{assign}

    这是{{variable}}


    使用$emit$broadcast,(如walv在上述评论中所述)

    向上触发事件(从子级到父级)

    向下触发事件(从父级到子级)

    最后是倾听

    $scope.$on('myTestEvent', function (event, data) {
      console.log(data);
    });
    
    详情如下:


    享受:)

    另外,$emit和$broadcast之间的区别在于$emit可以取消,而$broadcast不可以。您可能希望获得子范围的一个地方是单元测试指令时。如果您有一个transcluded指令,那么作用域是用于编译元素的作用域的子级。访问已编译指令的范围进行测试是一项挑战。谢谢。另一个选项可以是
    localStorage
    ,具有类似于
    ngStorage
    的依赖项。非常简洁明了。要添加到这一点,只需意识到没有绑定,所以当您像上面那样声明它时,parentScope.child此时持有child的作用域。要解决此问题,可以添加$scope.$watch(函数(){parentScope.child=$scope});因此,在每次摘要之后,它都会将新范围向上推送到父级。在父端,如果要在html中使用任何子作用域作为视觉效果,则需要在其子变量上添加一个watch,并告诉它这样更新作用域:$scope.$watch('child',function(){$scope.$evalAsync();})。希望这能节省一些时间@如果确实如此,我相信不需要$watch()。这些是对象,它们是通过引用传递的。@Swanidhi=我知道你的意思,我也这么认为,但在写评论的时候,当我进行实验时,它不起作用。值得一提的是,我从做这件事改为发射/广播。如何在类型脚本中做这件事?对我来说是最好的答案!!JavaScriptJS中作为引用处理的对象的最佳示例另外,请务必阅读以下内容:angularJS中作用域和继承的非常好和深入的概述。
    <div ng-controller="ParentController as parentCtrl">
       ...
    
        <div ng-controller="ChildController as childCtrl" 
             ng-init="ChildCtrl.init()">
           ...
        </div>
    </div>
    
    app.controller('ChildController',
        ['$scope', '$rootScope', function ($scope, $rootScope) {
        this.init = function() {
             $scope.parentCtrl.childCtrl = $scope.childCtrl;
             $scope.childCtrl.test = 'aaaa';
        };
    
    }])
    
    app.controller('ParentController',
        ['$scope', '$rootScope', 'service', function ($scope, $rootScope, service) {
    
        this.save = function() {
            service.save({
                a:  $scope.parentCtrl.ChildCtrl.test
            });
         };
    
    }])
    
    <!DOCTYPE html>
    <html>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
    <script type="text/javascript">
        var app = angular.module('myApp',[]);
    
        app.controller('child',function($scope){
            $scope.variable = "child";
            $scope.$parent.setValue($scope);
        });
    
        app.controller('parent',function($scope){
            $scope.setValue = function(childscope) {
                $scope.assign = childscope.variable;
            }
        });
    
    </script>
    <body ng-app="myApp">
     <div ng-controller="parent">
        <p>this is parent: {{assign}}</p>
        <div ng-controller="child">
            <p>this is {{variable}}</p>
        </div>
     </div>
    </body>
    </html>
    
    $scope.$emit('myTestEvent', 'Data to send');
    
    $scope.$broadcast('myTestEvent', {
      someProp: 'Sending you some data'
    });
    
    $scope.$on('myTestEvent', function (event, data) {
      console.log(data);
    });