Angular JS循环依赖

时间:2015-05-28 12:26:47

标签: javascript angularjs factory

我正在尝试使用angular将一些java移植到一个cordova应用程序并且遇到了一个循环依赖问题 - 经常被问到,但是说实话,我仍然没有更聪明。

我有两个对象 - 天体和轨道对象,它们可以相互引用。

class Orbit {
    double a; // Semi Major axis
    double e; // Eccentricity
    Body primary; // The primary body around which the orbit is centred

    double getPeriod() {
        if (a < 0) {
            return Double.POSITIVE_INFINITY;
        } else {
            return 2 * Math.PI * Math.sqrt(a * a * a / primary.mu);
        }
    }
}

class Body {
    double mu; // Gravitational parameter
    String name;
    double radius; // Surface radius
    Orbit orbit;

    double getSphereOfInfluence() {
        if (orbit.primary == null) {
            return Double.POSITIVE_INFINITY;
        } else {
            return orbit.a * Math.pow(mu / orbit.primary.mu, .4);
        }
    }
}

如果我们以月球为例,身体“月球”的轨道主要是“地球”,而“地球”又有一个主要是“太阳”的轨道等。

好处[IMO]是我可以有一组静态对象,所以如果我创建了许多轨道对象,它们都使用相同的主体而不是复制所有属性。这也意味着我可以可靠地通过系统。

我已经看到各种评论说循环依赖是“坏”,我读过Misko's blog about the subject,但我正在努力解决两件事 - 为什么它们“坏”,我将如何重构我的代码使用他的A,B,C方法编写“好”代码。

更新 - 我最终得到了

angular.module('starter.services', [])

.service("Bodies", function(Body, Orbit) {
  this.KERBOL = new Body({name: "Kerbol", mu: 1.17233279483249E+18, period: 432000, radius: 261600000});
  this.KERBIN = new Body({name: "Kerbin", mu: 3531600000000, period: 21600, radius: 600000, orbit:
      new Orbit({a: 13599840256, e: 0, primary: this.KERBOL})
    });

  this.find = function(name) {
    var found = null;

    angular.forEach(this, function(item, key) {
      if ((found == null) && (item instanceof Body) && (item.name === name)) {
        found = item;
      }
    });

    console.log("Found body: " + JSON.stringify(found));
    return found;
  };
})

.factory("Body", function() {
  function Body(params) {
    if (params) {
      this.mu = params.mu;
      this.name = params.name;
      this.period = params.period;
      this.radius = params.radius;
      this.orbit = params.orbit;
    }
  };

  Body.prototype = {
    get primary() { return this.orbit.primary; },

    getEscapeVelocity: function() {
      return Math.sqrt(2 * this.mu / this.radius);
    },

    getOrderValue: function() {
      var v = this.orbit.a;

      var body = this;
      while ((body = body.orbit.primary) !== null) {
        v += body.orbit.a;
      }

      return v;
    },

    getSphereOfInfluence: function() {
      if (this.orbit.primary == null) {
        return Number.POSITIVE_INFINITY;
      } else {
        return this.orbit.a * Math.pow(this.mu / this.orbit.primary.mu, .4);
      }
    },

    getSurfaceGravity: function() {
      return this.mu / (this.radius * this.radius);
    },

    getSynchronousAlt: function() {
      return this.getSynchronousRadius() - this.radius;
    },

    getSynchronousRadius: function() {
      throw "Not implemented";
    }
  };

  return (Body);
})

.factory("Orbit", function(Body) {
  function Orbit(params) {
    if (params) {
      this.a = params.a;
      this.e = params.e;
      this.epoch = params.epoch;
      this.i = params.i;
      this.omega = params.omega;
      this.lan = params.lan;
      this.M0 = params.M0;
      this.M = params.M;
      this.primary = params.primary;
    }
  };

  Orbit.prototype = {
  };

  return (Orbit);
})
});

1 个答案:

答案 0 :(得分:-1)

如果您可以使用c ++执行此操作,则可以在Orbit中执行Body * atribute并在Body中执行Orbit * atribute,然后停止多引用。 要使用它你只需要:myBody = new Body();

无论如何,我不认为两个不同的类相互引用是最好的方式......想另一种方式。