Ressource d'un objet hérité non chargée par les héritiers

Bonjour,
je suis je pense sur un cas un peu limite: j’ai une ressource (type SCRIPT front) définie sur un objet A qui est hérité par B.

La ressource de A n’est pas chargée par B. J’ai donc dupliqué le SCRIPT de A dans une ressource spécifiquement définie sur B.

Est-il envisageable que B hérite des ressources de A ?
Ou plus précisément que les hooks front de B soient par défaut initialisés avec le code des hooks de A…

// B front side hook
(function(ui) {
	if (!ui) return;
	var app = ui.getAjax();
	// Hook called by each object instance
	Simplicite.UI.hooks.B = Simplicite.UI.hooks.A
})(window.$ui);

Bonjour Bruno,

Oui ce serait effectivement une bonne chose d’avoir par défaut un héritage simple :

Simplicite.UI.hooks.B = Simplicite.UI.hooks.A

pour appliquer les mêmes comportement UI (sur les choses communes et si le code est bien compatible donc sans nommer explicitement l’objet ou l’instance…).

Mais dans une cas général c’est plus complexe.

  • La surcharge par override : il faut nécessairement redéfinir tous les hooks au niveau de B
  • L’héritage de code via super : là en javascript ça devient problématique…

Il faut définir une syntaxe pour pouvoir invoquer un hook de A à partir d’un hook de B (et récursivement tous les parents potentiels).

En Rhino les hook serveur était des fonctions JS statiques par objet donc on pouvait les appeler “en dur” :

MyChildObject.postCreate = function() {
    MyFatherObject.postCreate.call(this); // Call parent object hook
    // Do something specific to the child object
}

Mais sur la UI responsive, les hooks sont définits par instance dans le namespace locals.ui, on ne peut donc pas appeler un hook comme une fonction statique.

Il faut je pense faire évoluer cette partie pour qu’un objet front puisse pointer sur une instance parente en mémoire : obj.super.locals.ui par exemple, chaque instance connait son père (pas comme luke).

Je passe ce post en feature request car il va falloir se pencher sur la question.
En attendant on peut gérer l’héritage en front en appelant une fonction “commune” que chaque hook hérités viendrait appeler.

Bonjour François,
merci beaucoup pour ton retour.

Je me doutais que la solution était plus complexe que l’énoncé du problème…
La duplication du code permet de contourner le problème donc nous ne sommes pas bloqués.
Par ailleurs, la logique d’override implique de fait une duplication du code (il faut réimplémenter tout le bloc). La logique super permettrait en effet de factoriser sous réserve de pouvoir pointer sur le code hérité depuis le code héritier (pas trivial si j’ai bien compris).

Quel pattern est préconisé pour partager des ressources entre hérité/héritiers ? (cf. le code commun appelé dans les hooks front concernés)

Le SCRIPT du parent peut contenir des méthodes dans un namespace publique et qui pourront être appelées par d’autres hooks :

var myCommonMethods = myCommonMethods || {
	myMethod: function(ctn, obj) { /* ... */ }
};

(function(ui,$) {
	Simplicite.UI.hooks.A = function(o, cbk) {
		try {
			o.locals.ui.form.onload = function(ctn, obj) {
				myCommonMethods.myMethod(ctn, obj);
			};
		}
		catch(e) {
			app.error("Error in Simplicite.UI.hooks.A: "+e.message);
		}
		finally {
			cbk && cbk();
		}
	};
})(window.$ui, jQuery);

et dans B, ce sera le même code pour implémenter les hooks sans la déclaration des méthodes qui contient la logique métier commune.

(function(ui,$) {
	Simplicite.UI.hooks.B = function(o, cbk) {
		try {
			o.locals.ui.form.onload = function(ctn, obj) {
				myCommonMethods.myMethod(ctn, obj);
				// and then do something else...
			};
		}
		catch(e) {
			app.error("Error in Simplicite.UI.hooks.B: "+e.message);
		}
		finally {
			cbk && cbk();
		}
	};
})(window.$ui, jQuery);

En terme d’isolation c’est pas top donc il faut qu’on se penche sur les namespaces des héritiers pour qu’ils puissent appeler leurs hooks “entre-eux”.

1 Like

Simplicité à partir de la V5.3 (en beta) utilise du javascript ES6/ES7 côté front, on va voir pour améliorer la mécanique des hooks front sous forme de classes JS, donc avec possibilité d’hériter des hooks des objets parents côté UI.

L’ancienne syntaxe des hooks sera toujours supportée, et appelée en priorité si implémentée (mais ne pourra pas prétendre à l’héritage des hooks).

Les hooks “nouvelle génération” auront cette forme, il faudra créer une nouvelle ressource CLASS sur l’objet.

Exemple avec un objet A, ressource CLASS :

Simplicite.UI.BusinessObjects.A = class extends Simplicite.UI.BusinessObject {
	constructor(app, name, inst) {
		super(app, name, inst);
		console.log("[A].constructor");
	}
	onLoadForm(ctn, obj, p) {
		console.log("[A].onLoadForm");
	}
};

Et A2 qui hérite de A, ressource CLASS :

Simplicite.UI.BusinessObjects.A2 = class extends Simplicite.UI.BusinessObjects.A {
	constructor(app, name, inst) {
		super(app, name, inst);
		console.log("[A2].constructor");
	}
	onLoadForm(ctn, obj, p) {
		super.onLoadForm(ctn, obj, p);
		console.log("[A2].onLoadForm");
	}
};
  • Simplicite.UI.BusinessObject hérite de Simplicite.Ajax.BusinessObject avec tous les hooks par défaut (list, form…).
  • Il suffit d’utiliser la mécanique des “super” pour étendre ou écraser l’implémentation parente.
  • app.getBusinessObject sera plus malin pour instancier la bonne classe.

@bmo

1 Like

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.