如何從其父作用域調用在子作用域中定義的方法?angularJS:如何在父作用域中調用子作用域函數
function ParentCntl() {
// I want to call the $scope.get here
}
function ChildCntl($scope) {
$scope.get = function() {
return "LOL";
}
}
如何從其父作用域調用在子作用域中定義的方法?angularJS:如何在父作用域中調用子作用域函數
function ParentCntl() {
// I want to call the $scope.get here
}
function ChildCntl($scope) {
$scope.get = function() {
return "LOL";
}
}
您可以使用$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";
}
}
非常酷!但是,如果你不想(想)知道調用者範圍在哪裏(我的意思是在'$ scope。$ parent'或'$ scope。$ parent。$ parent'等中)?啊,是的:通過params傳遞迴調! :) – user2173353
@ user2173353你說得很對;還有一種方法:從孩子向父母發放'$ emit'。我認爲這是一個更新我的答案的時間。 – Cherniv
在這種情況下,調用全局監聽器是什麼地方,子控制器是個好主意嗎?它不是反模式,以後很難測試?我們不應該使用注射還是使用? – calmbird
讓我提出另一種解決方案:
var app = angular.module("myNoteApp", []);
app.controller("ParentCntl", function($scope) {
$scope.obj = {};
});
app.controller("ChildCntl", function($scope) {
$scope.obj.get = function() {
return "LOL";
};
});
更少的代碼,並使用原型繼承。
有人可以解釋一下,如果這種方法比上面提到的事件驅動方法更好,那麼在哪種情況下,爲什麼?如果您有多個lvl層次結構的子控制器會怎麼樣?如果obj.get是在子控制器內的子控制器內定義的,只要沒有控制器具有相同的函數名稱定義,這會工作嗎?先謝謝你。 – ZvKa
有趣......感謝您的評論,最讓我感動的是我認爲js prototypical/angularjs作用域的繼承只應用於一個方向.... child - >父或子作用域 - >父作用域,而不是其他方式周圍....但我想我失去了一些東西@ _ @ – ZvKa
讓我糾正我說的這是不完全正確的。你說的是正確的: 範圍繼承只適用於一個方向.... child - > parent。 這裏發生的實際情況是,如果您在子作用域中定義$ scope.get,則只會在子作用域(有時稱爲基本定義)上定義「get」。但是當你定義$ scope.obj.get時,子範圍將查找在父範圍上定義的obj,該範圍位於層次結構的上方。 – Canttouchit
註冊孩子的功能父當孩子被初始化。爲了使模板清晰,我使用了「as」符號。
模板
<div ng-controller="ParentCntl as p">
<div ng-controller="ChildCntl as c" ng-init="p.init(c.get)"></div>
</div>
CONTROLLERS
...
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
isn't supposed to be used this way!」。嗯,是的,但
我說這對它很好用。如果你想讓我失望,請評論和理由! :)
我喜歡這種方法,因爲它使組件更加模塊化。唯一綁定模板,並意味着
這種方法更密切地接近Tero's idea of modularising with directives(注那在他的modularis編輯示例,contestants
從父項傳遞到模板中的「子」指令)。
事實上,另一種解決方案可能是考慮將ChildCntl
作爲指令並使用&
綁定來註冊init
方法。
我知道這是一箇舊的帖子,但這似乎是一個壞主意,因爲父母可以在孩子被銷燬後保留對孩子的引用。 –
最好的辦法是定義一個服務,將這個服務注入兩個控制器。或者使用Rootcope。 – tymeJV