2013-08-26 7 views
23

In meinem Test gegeben 2 Dokument, A und B. In einem Dokument gibt es einen iframe, die iframe Quelle ist B-Dokument. Meine Frage ist, wie man B Dokument bestimmten Umfang der Variable ändert?Angularjs: anderen Bereich aufrufen, der in iframe

Hier ist mein Code: Ein Dokument

<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> 

Mein B Dokument:

<!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> 

Hinweis: Eigentlich ist es eine Möglichkeit, es zu tun, die ich es wie ein Gefühl, hacken statt der richtigen Weg, um es zu erledigen: das ist eine Schaltfläche in b Dokument erstellen, und binden Sie dann mit angularjs ng-klicken. Danach ein Dokument jquery "Trigger" klicken Sie auf die Schaltfläche.

+2

Nur eine kurze Notiz. Denken Sie daran, dass Sie normalerweise nicht mit einem iFrame und der übergeordneten Seite kommunizieren können, es sei denn, sie befinden sich in derselben Domäne. Es gibt Möglichkeiten, es zu tun, aber Sie können nicht nur direkt auf sie zugreifen. Nur damit Sie später nicht auf dieses Problem stoßen :) –

+0

Ja, es gibt dieselbe Domain und dasselbe Projekt. Ich kann das JS-Objekt und die Variable nicht richtig manipulieren. Ich frage mich, ob jemand eine bessere Idee hat. – Stupidfrog

Antwort

42

Für den Zugriff auf und in zwei Richtungen (Eltern iFrame, iFrame Elternteil), für den Fall, kommunizieren sie sind beide in der gleichen Domäne, mit Zugang zum Winkel Umfang, versuchen Sie diesen Schritten folgt:

* Sie don ‚muß t die übergeordneten Verweis auf AngularJS Bibliothek haben ...

Aufruf zum Kind iFrame von den Eltern

1.Get Kind iFrame-Element aus dem übergeordneten (link to answer):

document.getElementById ("myIframe") contentWindow

2. Greifen der Umfang des Elements:..

document.getElementById ("myIframe") contentWindow.angular.element (. "#someDiv") Umfang()

3.Call der Umfang der Funktion oder Eigenschaft:

document.getElementById ("myIframe"). ContentWindow.angular.element ("# someDiv"). Scope(). SomeAngularFunction (Daten);

4.Call $ scope.$ gilt nach Ausführen der Logik der Funktion/Aktualisieren der Eigenschaft (link to Mishko’s answer):

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

  • Eine andere Lösung ist es, den Umfang zwischen den iFrames zu teilen, aber dann müssen Sie in beiden Seiten Winkel: (link to answer and example)

Aufruf Eltern von Kind iFrame

  1. Aufruf der Elternfunktion:

parent.someChildsFunction();

Will auch auf aktualisieren, wie es Cross-Domain zu tun, wenn es notwendig ist ..

+5

Ich möchte hinzufügen, dass Sie den übergeordneten Bereich aus dem iFrame wie folgt greifen: 'var $ scope = parent.angular.element ('# Element-ID'). Scope();' –

+0

Urigo, das ist großartig und konsolidiert. Wie geht es Domain-übergreifend? – rajat

+0

Danke für die tolle Antwort. Angular 1.2x führte die $ evalAsync() -Methode ein, die vermeidet, dass $ timeout mit $ apply verwendet werden muss. Die Verwendung von $ timeout wurde in früheren Versionen von Angular empfohlen, um sicherzustellen, dass die Änderung im $ digest-Zyklus übernommen wird (andernfalls könnte es zu einem Race-Zustand kommen). – pmont

3

Der beste Weg, um mit dem Iframe zu kommunizieren, ist die Verwendung von window.top. Wenn Sie möchten, dass Ihr iframe den Bereich Ihres übergeordneten Elements abruft, können Sie window.scopeToShare = $scope; in Ihrem Controller festlegen und auf die iframe-Seite unter window.top.scopeToShare zugreifen.

Wenn Sie Ihre Eltern wollen den iframe Umfang zu erhalten, können Sie

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

und innerhalb des iframe-Controller Anruf window.top.giveRootScope($rootScope);

WARNUNG verwenden: Wenn Sie diese Controller mehrmals verwenden, stellen Sie sicher, Verwenden Sie eine zusätzliche ID, um den gewünschten Bereich zu identifizieren.

12

Sie sollten übergeordneten Bereich von iFrame in der Lage zu bekommen:

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

Dann können Sie Eltern-Methode aufrufen oder Änderung Mutter Variable (aber nicht vergessen, parentScope.$apply aufrufen, um die Änderungen zu synchronisieren)

getestet auf Angular 1.3.4

+2

Ich wünschte, ich könnte dies zweimal upgraden ... – baacke

+0

Das hat mich wirklich gerettet !! –

+0

WARNUNG! .scope() ist keine Produktionsmethode. Es dient nur zum Debuggen und wird im Produktionsmodus entfernt! https://docs.angularjs.org/guide/production –

Verwandte Themen