MOBILE-4163 siteplugins: Fix lifecycle overrides
parent
153c8a6d02
commit
06a2b23adb
|
@ -3,3 +3,5 @@ this.CoreSitesProvider.getSite().then(site => {
|
|||
|
||||
document.getElementById('username').innerText = `, ${username}`;
|
||||
});
|
||||
|
||||
this.ngAfterViewInit = () => this.CoreDomUtilsProvider.showToast('Lifecycle hook called');
|
||||
|
|
|
@ -173,6 +173,8 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy, DoCheck {
|
|||
// Create the component, using the text as the template.
|
||||
return class CoreCompileHtmlFakeComponent implements OnInit, AfterContentInit, AfterViewInit, OnDestroy {
|
||||
|
||||
private ongoingLifecycleHooks: Set<keyof AfterViewInit | keyof AfterContentInit | keyof OnDestroy> = new Set();
|
||||
|
||||
constructor() {
|
||||
// Store this instance so it can be accessed by the outer component.
|
||||
compileInstance.componentInstance = this;
|
||||
|
@ -222,21 +224,41 @@ export class CoreCompileHtmlComponent implements OnChanges, OnDestroy, DoCheck {
|
|||
* Content has been initialized.
|
||||
*/
|
||||
ngAfterContentInit(): void {
|
||||
// To be overridden.
|
||||
this.callLifecycleHookOverride('ngAfterContentInit');
|
||||
}
|
||||
|
||||
/**
|
||||
* View has been initialized.
|
||||
*/
|
||||
ngAfterViewInit(): void {
|
||||
// To be overridden.
|
||||
this.callLifecycleHookOverride('ngAfterViewInit');
|
||||
}
|
||||
|
||||
/**
|
||||
* Component destroyed.
|
||||
*/
|
||||
ngOnDestroy(): void {
|
||||
// To be overridden.
|
||||
this.callLifecycleHookOverride('ngOnDestroy');
|
||||
}
|
||||
|
||||
/**
|
||||
* Call a lifecycle method that can be overriden in plugins.
|
||||
*
|
||||
* This is necessary because overriding lifecycle hooks at runtime does not work in Angular. This may be happening
|
||||
* because lifecycle hooks are special methods treated by the Angular compiler, so it is possible that it's storing
|
||||
* a reference to the method defined during compilation. In order to work around that, this will call the actual method
|
||||
* from the plugin without causing infinite loops in case it wasn't overriden.
|
||||
*
|
||||
* @param method Lifecycle hook method name.
|
||||
*/
|
||||
private callLifecycleHookOverride(method: keyof AfterViewInit | keyof AfterContentInit | keyof OnDestroy): void {
|
||||
if (this.ongoingLifecycleHooks.has(method)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.ongoingLifecycleHooks.add(method);
|
||||
this[method]();
|
||||
this.ongoingLifecycleHooks.delete(method);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -13,3 +13,9 @@ Feature: Plugins work properly.
|
|||
|
||||
When I press "Moodle App Behat (auto-generated)" in the app
|
||||
Then I should find "studentusername" in the app
|
||||
|
||||
Scenario: Use lifecycle hooks
|
||||
Given I entered the app as "studentusername"
|
||||
When I press the more menu button in the app
|
||||
And I press "Moodle App Behat (auto-generated)" in the app
|
||||
Then I should find "Lifecycle hook called" in the app
|
||||
|
|
Loading…
Reference in New Issue