父模块作为依赖项

9

我的应用程序有一个 Angular 模块:

var io = angular.module('IO_Operations', []);

该模块还包括一个服务,用于实现输入/输出功能:
io.service('ioService', function () {
    var dataStore = {};

    return {
        pushData: function (key, value) {
            dataStore[key] = value;
        },
        getData: function (key) {
            return dataStore[key];
        }
    };
});

稍后我想将dataStore变量以JSON格式存储为对象到文件中。
现在我的应用程序中有一个iframe来显示一些带有选项卡的内容,您可以称之为浏览器。
为了能够进行一些设置,我想在一个iframe中完成它。为了将数据保存到文件中,我需要调用父应用程序中的IO_Service
我的iframe中有一个模块:
var settings = angular.module("settings", []);

使用控制器

settings.controller("MyController", function ($scope) { ... }

因此,我需要为父模块声明依赖项,以使用 ioService 并调用 pushData 函数。

有没有人能给我一些实现这个的技巧?


也许是个愚蠢的建议,但你可不可以把每个选项卡的设置和选项卡放在iframe之外呢?这样你就能够更好地控制它了。 - nacholibre
我现在是这样做的,选项卡只是加载HTML文档的iframe。我现在已经将设置直接实现在应用程序中,以便与我的其他控制器共享Angular魔法 :) - Ba5t14n
2个回答

1

这里DoctorMick所说的一切都是正确的,必须在控制器中完成以便访问服务。

此外,您需要解决父级和iframe之间没有共享任何Javascript上下文的问题:

同域名解决方案

在您的模块中,dataStore需要是window.dataStorewindow.parent.dataStore(或可能是window.top.datastore),具体取决于该模块是作为iframe加载还是作为主页面加载:

io.service('ioService', function () {
    var inIframe = (window.parent !== window); // or (window.top !== window);

    // If we are in the iframe, we want to use the parent's dataStore,
    // If we are not in the iframe, we are the parent, so use ours.
    var dataStore = inIframe ? window.parent.dataStore : window.dataStore;

    dataStore = dataStore || {};

    return {
        pushData: function (key, value) {
            dataStore[key] = value;
        },
        getData: function (key) {
            return dataStore[key];
        }
    };
});

或者类似的东西。基本上,要确定您是在iframe或父级中加载,并将其附加到自己的(作为父级)dataStore或父级的dataStore

跨域解决方案

主框架和iframe是完全独立的-它们几乎可以视为两个不同的浏览器选项卡-因此从Javascript数据角度来看,它们不共享任何内容。如果不使用某种类型的iframe通信库或使用api(通过WebSockets,也许?)进行支持,则无法使两个框架进行通信。

如果您将问题重新考虑为两个不同的应用程序-“浏览器容器”和一组“浏览器”-并寻找适当的应用程序之间的通信,那可能会有所帮助。

更具体地说,假设您需要一个客户端解决方案,您在ioService中的pushData(key, value)getData(key)方法只需要包装一个使用本机Window.postMessage API或类似postmessageporthole的通信机制。请保留HTML标签。

0
你所需要做的就是让设置模块知道它依赖于IO操作模块,一旦完成这个步骤,你就可以像在同一个模块中一样使用IO服务了,如下所示:
var settings = angular.module("settings", ["IO_Operations"]);

settings.controller("MyController", function ($scope, ioService) { ... }

1
设置模块在一个iframe中,使用这种方法不起作用,我需要告诉Angular它是父模块。无论如何,感谢您的帮助 :) - Ba5t14n
1
当我阅读问题时,我错过了那个相当关键的信息,真是太傻了。 :) 如果您在页面中使用angular和iframe,那么这不会给您两个单独的angular“实例”,而且它们之间没有任何通信的方式吗?您需要使用iframe的原因是什么? - DoctorMick
1
这是一个应用程序,基本上使用选项卡来显示多个网站,我认为在选项卡中设置会很酷,就像Firefox一样。 由于JavaScript也可以通信,因此我只需要使用parent.. 也许你是对的,因为我需要在我的设置网页中再次加载anular.js文件。 我考虑将设置放在另一个窗口中,也许更容易... - Ba5t14n
1
如果可能的话,似乎可以在父窗口和 iframe 之间进行通信,但需要使用事件而不是依赖项。我不会提供答案,因为我从未尝试过,但这个链接应该会有所帮助:http://charemza.name/blog/posts/angularjs/iframe/same-domain-iframe-communication/ - DoctorMick
1
谢谢,但在我尝试这个方法之前,我想试另一种方式: 我的想法是在父级中创建模块- parent.angular.module(...),这样依赖关系应该可以工作。现在我有问题,我需要在加载在 iframe 中的 HTML 文件中“执行”angular,但当我再次加载 angular 时,连接就会丢失(当然...),也许我可以从父级向下发送 angular 实例之类的东西,以便解决指令... - Ba5t14n

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接