2013-08-26 35 views
23

Trong thử nghiệm của tôi, được cung cấp 2 tài liệu, A và B. Trong tài liệu, có khung nội tuyến, nguồn khung nội tuyến là tài liệu B. Câu hỏi của tôi là làm thế nào để sửa đổi tài liệu B phạm vi nhất định của biến?Angularjs: gọi phạm vi khác trong iframe

Đây là mã của tôi: Một tài liệu

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

tài liệu của tôi 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> 

Lưu ý: Trên thực tế có một số cách để làm điều đó, mà tôi cảm thấy nó giống như một hack thay vì cách thích hợp để hoàn thành công việc: tạo nút trong tài liệu b, sau đó liên kết với angularjs ng-click. Sau đó một tài liệu jquery "kích hoạt" bấm vào nút.

+2

Chỉ là một lưu ý nhanh. Hãy nhớ rằng bạn không thể giao tiếp thường xuyên giữa iFrame và trang mẹ trừ khi chúng nằm trên cùng một miền. Có nhiều cách để làm điều đó, nhưng bạn không thể chỉ truy cập chúng trực tiếp. Chỉ để bạn không gặp vấn đề này sau :) –

+0

Có, có cùng tên miền và cùng một dự án. Chỉ cần không thể xử lý đúng đối tượng JS và biến đó. Tự hỏi liệu có ai có ý tưởng hay hơn không. – Stupidfrog

Trả lời

42

Để truy cập và giao tiếp theo hai hướng (cha mẹ để iFrame, iFrame để mẹ), trong trường hợp họ là cả hai trong cùng một tên miền, với quyền truy cập vào phạm vi góc, cố gắng sau những bước sau:

* Bạn don 't cần phụ huynh có tham chiếu đến thư viện angularJS ...

Gọi cho con iFrame từ mẹ

1.Get con yếu tố iFrame từ phụ huynh (link to answer):

document.getElementById ("myIframe") contentWindow

2.Access phạm vi của nguyên tố:..

document.getElementById ("myIframe") contentWindow.angular.element (. "#someDiv") phạm vi()

3.Call của phạm vi chức năng hay tài sản:

document.getElementById ("myIframe"). ContentWindow.angular.element ("# someDiv"). Scope(). SomeAngularFunction (dữ liệu);

4.Có $ phạm vi.$ áp dụng sau khi chạy logic của hàm/cập nhật thuộc tính (link to Mishko’s answer):

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

  • Một giải pháp khác là để chia sẻ phạm vi giữa iFrame, nhưng sau đó bạn cần góc ở cả hai phía: (link to answer and example)

Gọi mẹ từ con iFrame

  1. Gọi hàm chính:

parent.someChildsFunction();

Sẽ cập nhật cũng làm thế nào để làm điều đó miền chéo nếu nó là cần thiết ..

+5

Tôi muốn thêm rằng bạn có thể lấy phạm vi cha mẹ từ iframe như sau: 'var $ scope = parent.angular.element ('# element-id'). Scope();' –

+0

Urigo, điều đó thật tuyệt vời và hợp nhất, củng cố. Làm thế nào để làm điều đó qua miền? – rajat

+0

Cảm ơn câu trả lời tuyệt vời. Angular 1.2x đã giới thiệu phương thức $ evalAsync() để tránh phải sử dụng $ timeout với $ apply. Sử dụng $ timeout được đề xuất trong các phiên bản trước của Angular để đảm bảo rằng thay đổi sẽ được chọn trong chu kỳ $ digest (có thể kết thúc trong điều kiện chủng tộc khác). – pmont

3

Cách tốt nhất để liên lạc với iframe là sử dụng window.top. Nếu bạn muốn khung nội tuyến của mình có phạm vi của cha mẹ, bạn có thể đặt window.scopeToShare = $scope; trong bộ điều khiển của mình và nó có thể truy cập được cho trang iframe tại window.top.scopeToShare.

Nếu bạn muốn cha mẹ của bạn để có được phạm vi iframe, bạn có thể sử dụng

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

và trong cuộc gọi điều khiển iframe window.top.giveRootScope($rootScope);

CẢNH BÁO: Nếu bạn đang sử dụng điều khiển này nhiều lần, hãy chắc chắn để sử dụng một ID bổ sung để xác định phạm vi bạn muốn.

12

Bạn sẽ có thể để có được phạm vi cha mẹ từ iFrame:

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

Sau đó, bạn có thể gọi phương thức cha mẹ hoặc thay đổi biến mẹ (nhưng hãy nhớ gọi số parentScope.$apply để đồng bộ hóa các thay đổi)

Thử nghiệm trên góc 1.3.4

+2

Ước gì tôi có thể upvote điều này hai lần ... – baacke

+0

Điều này thực sự đã cứu tôi !! –

+0

CẢNH BÁO! .scope() không phải là phương thức sản xuất. Nó là để gỡ lỗi chỉ và được loại bỏ trong chế độ sản xuất! https://docs.angularjs.org/guide/production –

Các vấn đề liên quan