I have a similar problem in my janky homegrown ORM - bidirectional
parent-child has many and belongs to many type relationships are annoying
at times.

Personally, I do it by having an abstract base class that all the models in
my ORM derive from. In the concrete class declaration, I do something like
Model.registerChildConstructor('document', this). I use the coffeescript
form of classical inheritance.

That way I can do stuff like Model.findWithType('document', 2), or new
Model.childConstructors.document(). (I know - I should capitalize document
in that case, but I'm cheating because the "name" of the object is
lowercased and identical to the name of the table where I store the data,
which makes life easer). So when I get a chunk of data from my API, I can
do a data.map (v)->Model.findWithType(v.type, v.id) sorta thing.

I don't need to inject Document into model, because I already have access
to the constructor function, and in the subclasses, I can do
Model.findWithType just fine (since I have to inject the ABC in order to
inherit from it). My opinion is that circular dependencies are an example
of flawed code most of the time and should be avoided. Then again, I'm just
bypassing the angular complaints by using a string instead of a real object
to inject.

e


On Thu, May 29, 2014 at 2:47 AM, Antoine AGTHE <[email protected]>wrote:

> Hi Guyz,
>
> I got a typical cross dependency case that I solved, but I don't like my
> solution, as it's not that much elegant.
> The situation is the following:
>
> I have ElementA,and ElementB, that are "classes" (that can be
> instantiated).
> ElementA instance holds the ID of a ElementB object, and ElementB holds a
> list of ElementA IDs.
> It's like ElementB is a parent of ElementA objects, and an ElementAobject can 
> have only one parent.
>
> I have ElementAProvider and ElementBProvider, that are objects that can
> retrieve ElementA and ElementB data from a RESTful service.
> These service returns instances of class ElementA and ElementB.
>
> To make my objects easier to use, I added getParent() to ElementAprototype, 
> and
> getChildren() to ElementB prototype, so they returns instances of the
> parent, or the children, instead of just the ID. These methods use
> ElementAProvider et ElementBProvider to get these instances.
>
> ElementA.prototype = {
>     getParent  : function ()
>     {
>         return ElementBProvider.get( this.parentId );
>     }
> }
>
> ElementB.prototype = {
>     getChildren : function ()
>     {
>         return ElementAProvider.getSeveral( this.childrenIds );
>     }
> }
>
> The problem is, that when I add my factories to my module, I have to
> define my dependencies :
>
> module.factory( 'ElementA'        , [ '$http', '$q', 'ElementBProvider',
> factoryElementA ] );
> module.factory( 'ElementB'        , [ '$http', '$q', 'ElementAProvider',
> factoryElementB ] );
> module.factory( 'ElementAProvider', [ '$http', '$q', 'ElementA'        ,
> factoryElementAProvider ] );
> module.factory( 'ElementBProvider', [ '$http', '$q', 'ElementB'        ,
> factoryElementBProvider ] );
>
> So ElementA needs ElementBProvider, that needs ElementB, that needs
> ElementAProvider, that needs ElementA.
>
> To solve that, I use $injector to manually get dependencies just before
> using them.
>
> function factoryElementA ( $http, $q, $injector )
> {
>     var ElementBProvider = null;
>
>     function _getDependencies ()
>     {
>         if ( ElementBProvider == null ) $injector.get( 'ElementBProvider'
> );
>     }
>
>     function ElementA ( /* … */ )
>     {
>         // …
>     }
>
>     ElementA.prototype = {
>         getParent : function ()
>         {
>             _getDependencies();
>             return ElementBProvider.get( this.parentId );
>         }
>     }
> }
>
> module.factory( 'ElementA', [ '$http', '$q', '$injector', factoryElementA
> ] );
>
> It works, but each time I need to use my dependencies, I have to check
> them.
> Is there another smarter way to do it ?
>
> --
> You received this message because you are subscribed to the Google Groups
> "AngularJS" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/angular.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/d/optout.

Reply via email to