AngularJS:打开一个新的浏览器窗口,但仍然保留范围和控制器,以及服务

IT技术 javascript angularjs angularjs-scope angularjs-service angularjs-controller
2021-03-02 03:06:57

我正在编写一个 angularJS 应用程序。在这个特定的控制器中,我通过$window.open服务打开一个新的浏览器窗口但是在新窗口中,所有$scope变量都丢失了。

我尝试使用,window.parent但这不起作用。事实上,在新的浏览器窗口中,所有的应用服务、控制器或作用域都没有生效,这是真的吗?有没有办法打开一个新的浏览器窗口,但仍然使新窗口属于旧窗口中的同一个 angular 应用程序?我需要访问一些 angularJS 服务和打开那个新窗口的控制器的范围。这可能吗?

3个回答

没有 [直接] 方法可以使新窗口属于同一个 angular.js 应用程序,因为 angular 应用程序通常通过 ng-app 指令与初始化它的窗口的文档、窗口和事件相关联或者通过调用 angular.bootstrap。

但是,您可以为弹出窗口创建新的 angular module和应用程序。通过包含适当的 javascript 文件,您可以使用与原始应用程序相同的基本服务和控制器。

假设您的弹出窗口需要来自原始应用程序的数据,您可以使用从 window.open() 方法返回的 window 对象传递该数据。例如,在你的第一个 angular 应用程序中,像这样打开你的弹出窗口:

angular.module('originalModule').service('popupService', function(someOtherDataService) {

  var popupWindow = window.open('popupWindow.html');
  popupWindow.mySharedData = someOtherDataService.importantData;

});

一旦您的辅助“弹出”角度应用程序被初始化,它就可以通过读取 window.mySharedData 来引用共享数据。

您还可以在每个窗口中创建可以从另一个窗口调用的函数。弹出窗口可以通过使用 window.opener 属性回调到原来的窗口。(window.parent指的是frame的父窗口,你要window.opener)

[同意,我相信如果你研究了 angular 源代码,你会找到一些聪明的方法来为两个窗口使用相同的 angular 应用程序。这样的尝试超出了我今晚的野心。]

有意愿的地方,就有黑客:)
2021-04-17 03:06:57
这篇文章展示了一种实现 OP 想要的东西的方法
2021-04-22 03:06:57
嗨,我最终没有制作新的 angular 应用程序。我确实使用了您通过 window.mySharedData 设置共享数据的技术,实际上我认为您可以通过这些技术导出 $scope 和您需要的所有 $service。谢谢。
2021-04-30 03:06:57
@phamductri 如果您能分享您的最终代码,那将非常有帮助。
2021-05-04 03:06:57

由主窗口打开的窗口在架构上将无法与其父窗口共享相同的根范围。因为角度范围是按 DOM 元素定义的。您需要在子窗口中引导一个全新的 AngularJs 应用程序。

如果主窗口(父窗口)生成了一个托管另一个 AngularJs 应用程序的新窗口(子窗口),以下解决方案可能是可行的:从父窗口引用新生成的窗口的根范围,然后传递一个事件从父窗口通过子窗口的范围。像这样的东西:

子窗口上

$rootScope.$on("INTER_WINDOW_DATA_TRANSFER", function (data, args) {                   
            console.log("DATA RECEIVED: " + args.someData);
        });

在父窗口中,您可以获取定义ng-app属性的 DOM 元素(在子窗口中)(它是根范围)(伪代码):

var newWindowRef = $window.open("", "New Window", "width=1280,height=890,resizable=1");
var newWindowRootScope = newWindowRef.angular.element("#MY_ROOT_APP_ELEMENT_ID").scope();
newWindowRootScope.$broadcast("INTER_WINDOW_DATA_TRANSFER", {someData : "I'm data"});
这不是一个很好的解决方案。$window.open 在返回新窗口句柄之前不等待文档准备就绪。除非该窗口打开得非常快,否则引用子窗口的元素将返回 Undefined。此外,用户可能有一个弹出窗口阻止程序。最安全的方法是让孩子打电话给父母(window.opener)来获取它需要的东西。
2021-04-29 03:06:57

您可以使用 window 对象传递数据:

句法:

$window.open('<linkname>').<variableName> = "your data";

例子 :

$window.open('<linkname>').var1 = "value1";

(注意:- 这将打开新链接并设置变量数据)在新的页面控制器中,您可以使用访问变量 oldata = window.var1;