Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aurelia component registration through code #482

Closed
Kabe0 opened this issue Oct 20, 2016 · 14 comments
Closed

Aurelia component registration through code #482

Kabe0 opened this issue Oct 20, 2016 · 14 comments

Comments

@Kabe0
Copy link

Kabe0 commented Oct 20, 2016

I'm submitting a feature request

I was interesting in being able to register components through my JavaScript application instead of relying on RequireJs. I can see Aurelia could be capable of doing this but this is an area that I could not find much documentation on. Something like...

aurelia.resources.registerComponent( "element-name", $class );

before aurelia root is set.

Our main reason is that we actually have a config that allows us to override classes per client so having the ability to override a component would be a great piece of functionality for us.

Cheers,

Ian

@EisenbergEffect
Copy link
Contributor

So, depending on the customer you register the same element name with different class implementations?

@Kabe0
Copy link
Author

Kabe0 commented Oct 21, 2016

Yes. This is usually for small client adjustments as we get many minor customisation which can be more cost efficient to do small adjustments.

We have multiple modules that are joined together to make a global config, then we have a client config which can override any specification of the product. Basically it's a set of aliases or pointers that can be changed to point to something else. This allows us to adjust the flow of an app without having to always migrate it into core as a feature as some client changes tend to be very specific.

@Kabe0
Copy link
Author

Kabe0 commented Oct 21, 2016

I have been going through the framework today and have a kinda working example of what I am wanting...

The view may not always be an inline view this was just as a mockup...

` var dynamicName = "example";

        @inlineView( "<template><p><button click.trigger='sayHello()'>Testing</button> is only a test ${bacon}</p></template>" )
        class Testing
        {
            public bacon = "cheese";

            public constructor()
            {
            }

            sayHello()
            {
                alert(`hello ${this.bacon}`);
            }
        }

        // grabbing containers that are required.
        var template = aurelia.container.get(TemplatingEngine);
        var moduleAnalyzer = aurelia.container.get(ModuleAnalyzer) as ModuleAnalyzer;

        var loadContext = new ResourceLoadContext();
        var analysis = moduleAnalyzer.analyze( dynamicName, Testing );
        analysis.initialize(aurelia.container);
        var analyzed = analysis as ResourceModule;

        analyzed.load( aurelia.container, loadContext );
        analyzed.register( aurelia.resources, dynamicName );`

@Kabe0
Copy link
Author

Kabe0 commented Oct 21, 2016

Mixed up the register and load ... had to setup a Promise to time all the requests...

            var allAnalysis = new Array(this._components.length);

            for( var i = this._components.length; i--; )
            {
                var component = this._components[i];

                // grabbing containers that are required.
                var moduleAnalyzer = aurelia.container.get(ModuleAnalyzer) as ModuleAnalyzer;

                var loadContext = new ResourceLoadContext();

                var r = metadata.getOrCreateOwn(metadata.resource, HtmlBehaviorResource, component.classType ) as any;
                r.elementName = component.name;

                var normalizedId = Origin.get(component.classType).moduleId;
                var analysis = moduleAnalyzer.analyze( normalizedId, component.classType );

                analysis.initialize(aurelia.container);
                analysis.register( aurelia.resources, component.name );

                allAnalysis[i] = analysis.load( aurelia.container, loadContext );
            }

            Promise.all(allAnalysis).then(function () {

                aurelia.setRoot( 'Adapters/AureliaRoot', document.body );
            });

@EisenbergEffect
Copy link
Contributor

I'm pretty impressed. If you are interested I'd be happy to work with you to create a new API to help out with this type of scenario. In theory, we should be able to reuse code from the View Engine to do this. Have a look there and think about what a generic implementation would be like. We might just need a friendlier API on top of what is already present.

@Kabe0
Copy link
Author

Kabe0 commented Oct 21, 2016

Sure, I'll take a look

@Kabe0
Copy link
Author

Kabe0 commented Oct 22, 2016

I have only been using the framework for a day (so still learning the bit's and pieces)... But to me this seems intuitive...

I could see it as an entity that can be used so someone can track modifications they make as they build out their Component. A ViewModelBuilder would handle making manipulations to the Component. The entity returned on the generation methods is mostly just a pointer for the ViewModelBuilder to track and to help the user understand what Component they are applying manipulations too. This could help give access to some of those decorator metadata functions as well.


            var viewModelBuilder = aurelia.container.get( ViewModelBuilder ) as ViewModelBuilder;

            var viewMod = viewModelBuilder.generateFromClass( className );
            var viewMod2 = viewModelBuilder.generateFromModule( moduleName );

            viewModelBuilder.assignViewFromUrl( viewMod, "url-path" );
            viewModelBuilder.assignCustomElement( viewMod, "element name" );

            viewEngine.loadViewModels( viewMod, viewmod2 );

importViewResources method could have it's anonymous method separated (line 217) and then called by both importViewResources and the loadviewModels methods

@eib
Copy link

eib commented Jun 9, 2017

+1 (sounds cool)

@Alexander-Taran
Copy link

Should become part of an epic.
this one..
enhancing iframes on load
and .destroy() or .reset()

very interested in the subject.. going to write some spec of wanted features/behaviors

@Alexander-Taran
Copy link

yet not writing the spec

@bigopon
Copy link
Member

bigopon commented Mar 22, 2018

This is the inspiration for the PR at aurelia/framework#858 It does a bit more than this as well. With that PR getting merged, we can probably close this

@Alexander-Taran
Copy link

I was being self observing.. gave a promise to write something.. yet I'm not going to.. so far..
Just noted it..
I've seen a lot of comments like "going to look @ it this weekend.." dated half a year ago.. and that is the last comment..
(-:

@Alexander-Taran
Copy link

Alexander-Taran commented Jan 7, 2019

I think it's mostly done in vCurrent and definitely works in vNext

@EisenbergEffect can be closed

@JSeligsohn
Copy link

@Kabe0 Hey, i know it's been a while since this issue was opened. Any luck getting this to work? Have you done it using the current version of Aurelia? I have a very similar use case I'm interested in.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants