2013-08-26 8 views
23

W moim teście, biorąc pod uwagę 2 dokumenty, A i B. W dokumencie znajduje się element iframe, źródłem iframe jest dokument B. Moje pytanie brzmi: jak zmodyfikować B dokumentować pewien zakres zmiennej?Angularjs: wywołaj inny zakres, który w iframe

Oto mój kod: 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> 

Mój dokument 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> 

Uwaga: Faktycznie jest jakiś sposób na to, co czuję, że jak włamać się zamiast właściwego sposobu, aby to zrobić: czyli utworzyć przycisk w b Dokument, a następnie powiązać z angularjs ng-click. Następnie kliknij przycisk "wyzwalacz" jQuery dokumentu.

+2

Krótka notka. Pamiętaj, że zazwyczaj nie można komunikować się między ramką iFrame a stroną nadrzędną, chyba że znajdują się one w tej samej domenie. Są sposoby, aby to zrobić, ale nie możesz po prostu uzyskać do nich bezpośredniego dostępu. Po prostu nie napotkasz tego problemu później :) –

+0

Tak, istnieje ta sama domena i ten sam projekt. Po prostu nie można poprawnie manipulować tym obiektem i zmienną JS. Zastanawiasz się, czy ktoś ma lepszy pomysł. – Stupidfrog

Odpowiedz

42

Aby uzyskać dostęp i komunikację w obu kierunkach (rodzic iFrame, iFrame do rodzica), w przypadku oba są w tej samej domenie, z dostępem do zakresu kątowego, spróbuj po tych krokach:

* don „t trzeba rodzica mieć odniesienie do biblioteki angularjs ...

Wywołanie do dziecięcej iFrame z rodzica

1.Get dziecko iFrame elementem od rodzica (link to answer):

document.getElementById ("myIframe") contentWindow

2.Access zakres elementu..

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

3.Call na zakres funkcji lub właściwości:

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

4.Call $ scope.$ stosuje się po uruchomieniu logiki funkcji/aktualizacji właściwości (link to Mishko’s answer):

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

  • Innym rozwiązaniem jest podzielenie zakresu między iFrames, ale wtedy trzeba kątowa po obu stronach: (link to answer and example)

Wywołanie rodzica z dzieckiem iFrame

  1. Wywołanie funkcji nadrzędnej:

parent.someChildsFunction();

zaktualizuje również, w jaki sposób to zrobić domeny krzyż, jeśli jest to konieczne ..

+5

Chciałbym dodać, że możesz przechwycić zakres nadrzędny z elementu iframe w następujący sposób: 'var $ scope = parent.angular.element ('# element-id'). Scope();' –

+0

Urigo, to jest świetne i skonsolidowany. Jak zrobić to między domenami? – rajat

+0

Dzięki za wspaniałą odpowiedź. Angular 1.2x wprowadził metodę $ evalAsync(), dzięki której nie trzeba używać $ timeout z $ apply. Używanie opcji $ timeout było zalecane w starszych wersjach Angular, aby zagwarantować, że zmiana zostanie pobrana w cyklu $ digest (może zakończyć się w innym przypadku wyścigu). – pmont

3

Najlepszym sposobem na komunikowanie się z ramką iframe jest użycie window.top. Jeśli chcesz, aby element iframe uzyskiwał zasięg rodzica, możesz ustawić window.scopeToShare = $scope; w kontrolerze i będzie on dostępny dla strony iframe pod adresem window.top.scopeToShare.

Jeśli chcesz aby twój rodzic, aby uzyskać zakres iframe, można użyć

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

iw ramach wezwania kontrolera iframe window.top.giveRootScope($rootScope);

Ostrzeżenie: Jeśli używasz tego kontrolera wielokrotnie, upewnij się, użyj dodatkowego identyfikatora, aby określić odpowiedni zakres.

12

Powinieneś być w stanie uzyskać z zakresu nadrzędnego iFrame:

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

Następnie można wywołać metodę nadrzędnej lub zmienna zmiana rodzic (ale pamiętaj, aby zadzwonić parentScope.$apply zsynchronizować zmiany)

Testowane na Kątowymi 1.3.4

+2

Żałuję, że nie mogłem tego dwa razy powtórzyć ... – baacke

+0

To naprawdę mnie uratowało !! –

+0

OSTRZEŻENIE! .scope() nie jest metodą produkcji. Jest przeznaczony tylko do debugowania i jest usuwany w trybie produkcyjnym! https://docs.angularjs.org/guide/production –

Powiązane problemy