AngularJS: как вызвать функцию дочернего объекта в родительском пространстве
Как вызвать метод, определенный в области дочерних объектов, из его родительской области?
function ParentCntl() {
// I want to call the $scope.get here
}
function ChildCntl($scope) {
$scope.get = function() {
return "LOL";
}
}
http://jsfiddle.net/wUPdW/
Ответы
Ответ 1
Вы можете использовать $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/
UPDATE. Существует еще одна версия, менее связанная и более проверяемая:
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";
}
}
Fiddle: http://jsfiddle.net/uypo360u/
Ответ 2
Позвольте мне предложить другое решение:
var app = angular.module("myNoteApp", []);
app.controller("ParentCntl", function($scope) {
$scope.obj = {};
});
app.controller("ChildCntl", function($scope) {
$scope.obj.get = function() {
return "LOL";
};
});
Меньше кода и использование прототипического наследования.
Plunk
Ответ 3
Зарегистрируйте дочернюю функцию родителя, когда ребенок инициализируется. Я использовал "как" для ясности в шаблоне.
TEMPLATE
<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
не предполагается использовать таким образом!". Ну, да, но
- что документация не объясняет, почему нет, и
- Я не считаю, что авторы документации рассматривали ВСЕ возможные варианты использования.
Я говорю, что это хорошо для этого. Если вы хотите сфокусировать меня, прокомментируйте причины!:)
Мне нравится этот подход, потому что он сохраняет компоненты более модульными. Единственные привязки находятся в шаблоне и означают, что
- дочерний контроллер не должен знать ничего о том, какой объект добавить свою функцию (как в ответе @canttouchit)
- родительский элемент управления может использоваться с любым другим дочерним элементом управления, который имеет функцию get
- не требует широковещательной передачи, которая будет очень уродливой в большом приложении, если вы не будете строго контролировать пространство имен событий
Этот подход более приближен к Идея теро модуляции с директивами (обратите внимание, что в его модульном примере contestants
передается из родительской в "дочернюю" директиву IN THE ОБРАЗЕЦ).
Действительно, другим решением может быть рассмотрение реализации ChildCntl
в качестве директивы и использование привязки &
для регистрации метода init
.