96

如何从其父范围调用在子范围中定义的方法?

function ParentCntl() {
    // I want to call the $scope.get here
}

function ChildCntl($scope) {
    $scope.get = function() {
        return "LOL";    
    }
}

http://jsfiddle.net/wUPdW/

4

4 回答 4

147

您可以$broadcast从父母到孩子使用:

function ParentCntl($scope) {

    $scope.msg = "";
    $scope.get = function(){
        $scope.$broadcast ('someEvent');
        return  $scope.msg;        
    }
}

function ChildCntl($scope) {               
    $scope.$on('someEvent', function(e) {  
        $scope.$parent.msg = $scope.get();            
    });

    $scope.get = function(){
        return "LOL";    
    }
}

工作小提琴:http: //jsfiddle.net/wUPdW/2/

更新:还有另一个版本,耦合度更低,可测试性更强:

function ParentCntl($scope) {
    $scope.msg = "";
    $scope.get = function(){
        $scope.$broadcast ('someEvent');
        return  $scope.msg;        
    }

    $scope.$on('pingBack', function(e,data) {  
        $scope.msg = data;        
    });
}

function ChildCntl($scope) {               
    $scope.$on('someEvent', function(e) {  
        $scope.$emit("pingBack", $scope.get());        
    });

    $scope.get = function(){
        return "LOL";    
    }
}

小提琴:http: //jsfiddle.net/uypo360u/

于 2013-09-26T21:20:19.527 回答
35

让我建议另一种解决方案:

var app = angular.module("myNoteApp", []);


app.controller("ParentCntl", function($scope) {
    $scope.obj = {};
});

app.controller("ChildCntl", function($scope) {
    $scope.obj.get = function() {
            return "LOL";    
    };
});

更少的代码和使用原型继承。

普朗克

于 2014-12-14T14:02:31.073 回答
13

当孩子初始化时,在父母上注册孩子的功能。为了在模板中清晰起见,我使用了“as”表示法。

模板

<div ng-controller="ParentCntl as p">
  <div ng-controller="ChildCntl as c" ng-init="p.init(c.get)"></div>
</div>

控制器

...
function ParentCntl() {
  var p = this;
  p.init = function(fnToRegister) {
    p.childGet = fnToRegister;
  };
 // call p.childGet when you want
}

function ChildCntl() {
  var c = this;
  c.get = function() {
    return "LOL";    
  };
}

“但是”,你说,“ng-init 不应该这样使用!”。嗯,是的,但是

  1. 该文档没有解释为什么不解释,并且
  2. 我不相信文档作者考虑了所有可能的用例。

我说这是一个很好的用途。如果您想对我投反对票,请在评论中说明理由!:)

我喜欢这种方法,因为它使组件更加模块化。唯一的绑定在模板中,这意味着

  • 子控制器不必知道将其功能添加到哪个对象(如@canttouchit 的回答)
  • 父控件可以与任何其他具有 get 功能的子控件一起使用
  • 不需要广播,除非您严格控制事件命名空间,否则这在大型应用程序中会变得非常丑陋

这种方法更接近于Tero 使用指令模块化的想法(请注意,在他的模块化示例中,contestants在模板中从父指令传递到“子”指令)。

实际上,另一种解决方案可能是考虑将 实现ChildCntl为指令并使用&绑定来注册该init方法。

于 2015-05-14T12:27:31.877 回答
-1

您可以制作子对象。

var app = angular.module("myApp", []);


app.controller("ParentCntl", function($scope) {
    $scope.child= {};
    $scope.get = function(){
      return $scope.child.get(); // you can call it. it will return 'LOL'
    }
   // or  you can call it directly like $scope.child.get() once it loaded.
});

app.controller("ChildCntl", function($scope) {
    $scope.obj.get = function() {
            return "LOL";    
    };
});

这里 child 正在证明 get 方法的目的地。

于 2018-08-14T13:20:43.437 回答