当前位置: 首页 > 面试题库 >

AngularJS中的循环依赖和OOP问题

呼延骏俊
2023-03-14
问题内容

我已经成功地将AngularJs与OOP结合使用了一段时间,所提供的方法允许您将类定义为angular服务,以后可以像这样扩展或继承:

Application.factory('AbstractObject', [function () {
    var AbstractObject = Class.extend({
        virtualMethod: function() {
           alert("Hello world");
        },
        abstractMethod: function() { // You may omit abstract definitions, but they make your interface more readable
           throw new Error("Pure abstract call");
        }
    });

    return AbstractObject; // You return class definition instead of it's instance
}]);

Application.factory('DerivedObject', ['AbstractObject', function (AbstractObject) {
    var DerivedObject = AbstractObject.extend({
        virtualMethod: function() { // Shows two alerts: `Hey!` and `Hello world`
            alert("Hey!");

            this._super();
        },
        abstractMethod: function() {
            alert("Now I'm not abstract");
        }
    });

    return DerivedObject;
}]);

使用所描述的方法使您能够定义完美地集成到角度基础架构中的类。您可以从OOP和AngularJs这两个世界获得各种漂亮的功能。依赖注入对于您的类是免费的,它使您的类变得简单,允许将许多样板控制器代码放入某些基类中,以便以后重用。

然而

AngularJs的基础架构阻止了前面描述的方法将其翅膀扩展到所有100%。当您尝试定义递归类定义(即递归聚合)时,会出现问题,例如您有两个类定义,例如BlogTag

Application.factory('Blog', ['Tag', function (Tag) {
    var Blog = Class.extend({
        tags: function() {
            return this.tags;
        }
    });

    return Blog;
}]);

Application.factory('Tag', ['Blog', function (Blog) {
    var Tag = Class.extend({
        Blogs: function() {
           return this.blogs;
        }
    });

    return Tag;
}]);

这是行不通的,因为BlogTag都自引用,导致循环依赖。

P.S

最后一件事,我发现了一种难看的解决方案,可以解决我的特定情况下的问题,但通常无法正常工作,而且正如我所说,它也不是很漂亮:

Application.factory('BlogNamespace', [function () {
    var Blog = Class.extend({
        tags: function() {
            return this.tags;
        }
    });

    var Tag = Class.extend({
        Blogs: function() {
           return this.blogs;
        }
    });

    return {
        Tag: Tag,
        Blog: Blog
    };
}]);

Question

由于名称空间也可能是循环依赖的主题,因此上述修复方法将无效。这意味着它不是描述问题的解决方案,而是现在的一个更深层次的问题。

关于在一般情况下如何解决所描述问题的任何建议?


问题答案:

我之所以回答自己的问题,只是因为我找到了一种技术方法来解决最初发布的问题。但是在此之前,我强烈建议您使用Blackhole的建议,因为它可以解决通常由不良体系结构引起的更广泛的问题。请优先使用他的方法,如果您知道自己在做什么,请返回到当前方法。

因此,这里去:

您可以$injector在运行时使用服务并注入所需的定义,从技术角度来看,这是合法的,但是根据这篇文章(很难想象它是在2008年编写的),这就像一个黑魔法,它会反击你:

Application.factory('Blog', ['$injector', function ($injector) {
    var Tag = $injector.get('Tag'); // Here is your tag

    ...    
}]);

Application.factory('Tag', ['Blog', function (Blog) {
    ...
}]);

编辑
事实证明,当前方法是服务定位器模式的一个示例,即IoC反模式。



 类似资料:
  • 问题内容: 我正在设计一个系统,其中包含两个模块,一个模块孕育文件,另一个模块。对于某些逻辑运算,它们需要彼此提供的服务。 每个模块都由一个单例表示,该单例实现一个接口,该接口向彼此提供一些服务,并带有抽象工厂来提供它们,如下所示: 文件模块的主类是这样的: 我不确定自己是否正确处理了循环依赖。有什么办法可能会意外中断? 编辑 :正如下面已回答的那样,处理此问题的正确方法是注射。但是,解决此问题的

  • 问题内容: 我有两个文件和,分别定义了两个类和。 直到今天,用于引用该对象的定义,因此我已经做了 在文件中。 但是,到目前为止,我已经为引用该对象的对象创建了一个新方法。 尝试导入时遇到了问题:我尝试了一下,当程序运行并调用了using的方法时,出现了一个未定义的异常。 我该怎么办? 问题答案: 导入Python模块 是一篇很棒的文章,介绍了Python中的循环导入。 解决此问题的最简单方法是将路

  • 我在一个ARM模板中有两个相互依赖的Azure资源:一个密钥库和一个service fabric集群。 是否有一种方法可以引用service fabric集群的对象ID来提供给密钥库的访问策略,是否有一种方法可以在不硬编码任何值的情况下生成密钥库中的机密?理想情况下,我们只知道秘密名称,并且只将该秘密名称提供给ARM模板中的服务fabric集群。

  • 问题内容: 我有以下课程。 和 可以清楚地看到,这些类之间存在循环依赖关系。如果尝试运行A类,最终会得到。 如果创建了一个依赖图,其中节点是类,则可以轻松地识别这种依赖关系(至少对于节点很少的图)。那么,为什么JVM至少在运行时无法识别此身份?JVM至少可以在开始执行之前发出警告,而不是抛出。 [更新] 某些语言不能具有循环依赖关系,因为这样就无法构建源代码。和可接受的答案。如果循环依赖性是C#的

  • 问题内容: 我有一个模块化的maven项目,其中两个模块“ BIZ”和“ EJB”包含如下内容: 如您所见, “ EJB”依赖于“ BIZ”, 因为它使用 MyClassX (实际上,它使用了BIZ的几种类别)。这就是 ImplFactory 使用反射实例化 InterfaceImpl 的原因。问题是 cl.newInstance() 将抛出 ClassCastException, 因为这两个模块

  • 问题内容: 我目前在设计类时遇到循环依赖问题。 自从我了解Anemic域模型(我一直在做的事情)以来,我一直在努力摆脱创建仅仅是“ getter和setter的存储桶”的域对象,并回到我的OO根。 但是,下面的问题是我遇到的很多问题,我不确定应该如何解决。 假设我们有一个 Team 类,其中有很多 Player 。这是什么运动都没有关系:)球队可以添加和删除球员,就像球员离开球队并加入另一个球队一