Ad

Dynamically Update AngularJS Component Definition

- 1 answer

I'm looking for a way to dynamically update a component, I have an object containing the information about the component (name, functions, variables, services, template, bindings, etc.). Then I generate the component dynamically using this data. And I need to regenerate the component whenever the definition is changed.

angular.module('components', [])
  .component('dynamicComponent', {
    bindings,
    template,
    controller
  })

angular.module('app', ['components'])

Is there a way to update the component that has been already registered on a module? or is there a way to update the module itself?

so far I've tried recreating the components module like so:

angular.module('components', [])
  .component('dynamicComponent', {
     ...newData
  })

but nothing happens. I also tried recompiling the element after I recreated the module. Still nothing happens.

I also tried calling angular.bootstrap after creating the modules but I found out that is not possible without destroying the element bootstrapped. It's throwing an error saying the element was already bootstrapped.

My goal here is to dynamically update the component definition, on the fly, without reloading the page.

Ad

Answer

I was able to do this by destroying the bootstrapped element, recreating that element, and calling angular.bootstrap again with the new updated modules and components.

Here's an example,
The initial code:

<body>
  <div id="app" ng-controller="MainController as $ctrl">
    <dynamic-component data="$ctrl.data">
    </dynamic-component>
  </div>
</body>
angular.module('components', [])
  .component('dynamicComponent', {
    bindings: {...},
    controller,
    template
  })

angular.module('app', ['components'])
  .controller('MainController', ...)

angular.bootstrap(document.querySelector('#app'), ['app'])

And to update dynamic-component, reset and destroy the bootstrapped element. Doing so will enable us to call angular.bootsrap on this element again

document.body.innerHTML = `
<div id="app" ng-controller="MainController as $ctrl">
  <dynamic-component data="$ctrl.data">
  </dynamic-component>
 </div>
`

Define your modules. Here, we can update the old dynamic-component however we want to. We can also add more components or modules.

angular.module('components', [])
  .component('newDynamicComponent', {
    bindings: ...newBindings,
    controller: newController,
    template: newTemplate
  })
angular.module('app', ['components', ...otherModules])
  .controller('MainController', ...)

angular.boostrap(document.querySelector('app'), ['app'])

Working example

If there's a better way, please let me know.

Ad
source: stackoverflow.com
Ad