2013-08-26 90 views
23

在我的測試中,給出了2個文件,A和B.在一個文件中,有一個iframe,iframe源是B文件。我的問題是如何修改B文件某些範圍的變量?Angularjs:調用iframe中的其他範圍

這裏是我的代碼:文檔

<html lang="en" ng-app=""> 
<head> 
    <meta charset="utf-8"> 
    <title>Google Phone Gallery</title> 
    <script type='text/javascript' src="js/jquery-1.10.2.js"></script> 
    <script type='text/javascript' src="js/angular1.0.2.min.js"></script> 
    <script> 
    var g ; 
function test($scope,$http,$compile) 
{ 
    $scope.tryget = function(){ 

     var iframeContentWindow = $("#iframe")[0].contentWindow; 
     var iframeDOM = $("#iframe")[0].contentWindow.document; 
     var target = $(iframeDOM).find("#test2"); 
     var iframeAngular = iframeContentWindow.angular; 
     var iframeScope = iframeAngular.element("#test2").scope(); 
     iframeScope.parentcall(); 
     iframeContentWindow.angular.element("#test2").scope().tempvalue = 66 ; 
     iframeScope.tempvalue = 66; 
     iframeContentWindow.tt = 22; 
     iframeScope.parentcall(); 
     console.log(iframeScope.tempvalue); 
     console.log(angular.element("#cont").scope()); 
    } 
} 

    </script> 
</head> 
<body> 

<div ng-controller="test"> 
     <div id="cont" > 
      <button ng-click="tryget()">try</button> 
     </div> 
</div> 
<iframe src="test2.html" id="iframe"></iframe> 

</body> 
</html> 

我的B原稿:

<!doctype html> 
<html lang="en" ng-app=""> 
<head> 
    <meta charset="utf-8"> 
    <title>Google Phone Gallery</title> 
    <script type='text/javascript' src="js/jquery-1.10.2.js"></script> 
    <script type='text/javascript' src="js/angular1.0.2.min.js"></script> 
    <script> 
var tt =11; 
function test2($scope,$http,$compile) 
{ 
    console.log("test2 controller initialize"); 
    $scope.tempvalue=0; 
    $scope.parentcall = function() 
    { 
     $scope.tempvalue = 99 ; 
     console.log($scope.tempvalue); 
     console.log(tt); 
    } 
} 

    </script> 
</head> 
<body> 

<div ng-controller="test2" id="test2"> 
     <div id="cont" > 
      <button ng-click="parentcall()">get script</button> 
     </div> 
     {{tempvalue}} 
</div> 

</body> 
</html> 

注:其實有一些方法來做到這一點,我覺得它像一個黑客而不是正確的方式來完成它: 這是在b文檔中創建一個按鈕,然後用angularjs ng-click綁定。之後,一個文件jQuery「觸發」點擊按鈕。

+2

只是一個快速的筆記。請記住,除非它們位於同一個域中,否則通常無法與iFrame和父頁面進行通信。有辦法做到這一點,但你不能直接訪問它們。只是這樣你纔不會遇到這個問題:) –

+0

是的,有相同的域和相同的項目。只是不能正確操縱這些JS對象和變量。想知道是否有人有更好的主意。 – Stupidfrog

回答

42

要訪問並在兩個方向上(父的iFrame,iFrame來父母)進行通信,在情況下,它們都在相同的域,可訪問的角度範圍,嘗試以下這些步驟:

*你不「T需要家長有參考angularJS庫...

從父調用到孩子的iFrame從父(link to answer

1.Get子iframe元素:

的document.getElementById( 「myIframe」)contentWindow

2.Access元素的範圍:。

的document.getElementById( 「myIframe」)contentWindow.angular.element( 「#someDiv」)範圍()

3.Call範圍的功能或屬性:

document.getElementById(「myIframe」)。contentWindow.angular.element(「#someDiv」)。scope()。someAngularFunction(data);

4.調用$ scope。$ apply在運行函數邏輯/更新屬性後(link to Mishko’s answer):

$ scope。$ apply(function(){});

從子調用父的iFrame

  1. 調用父功能:

parent.someChildsFunction();

也將更新關於如何做到這一點跨域如果有必要..

+5

我想補充一點,你可以像這樣從iframe中獲取父範圍:'var $ scope = parent.angular.element('#element-id')。scope();' –

+0

Urigo,這很棒,合併。如何做到跨域? – rajat

+0

感謝您的好評。 Angular 1.2x引入了$ evalAsync()方法,它避免了在$ apply中使用$ timeout。在早期版本的Angular中,建議使用$ timeout來保證在$ digest循環中可以找到更改(否則最終會出現競爭狀態)。 – pmont

3

在我心目中與iframe進行通信的最佳方式是使用window.top。如果你想讓你的iframe獲得你父母的範圍,你可以在你的控制器中設置window.scopeToShare = $scope;,並且可以通過window.top.scopeToShare的iframe頁面訪問它。

如果你希望你的父母得到iframe的範圍,你可以使用

window.receiveScope = function(scope) { 
    scope.$on('event', function() { 
    /* Treat the event */ 
    } 
}; 

和IFRAME控制器呼叫window.top.giveRootScope($rootScope);

警告中:如果你正使用該控制器多次,確保使用額外的ID來標識您想要的範圍。

12

您應該能夠從獲得的iFrame父範圍:

var parentScope = $window.parent.angular.element($window.frameElement).scope(); 

然後就可以調用父類的方法或改變親本可變(但記得調用parentScope.$apply同步的改變)

測試在角1.3.4

+2

希望我可以upvote這兩次... – baacke

+0

這真的救了我! –

+0

警告! .scope()不是一種生產方法。它僅用於調試,並在生產模式下被刪除! https://docs.angularjs.org/guide/production –