ASP.Net ScriptControl: chiama un metodo da un altro
-
03-07-2019 - |
Domanda
Supponi di avere due controlli di script e un controllo ha l'altro come controllo figlio:
ParentControl : ScriptControl
{
ChildControl childControl;
}
Lo script per Child Control:
ChildControl = function(element)
{
ChildControl.initializeBase(this, [element]);
}
ChildControl.prototype =
{
callMethod: function()
{
return 'hi';
},
initialize: function()
{
ChildControl.callBaseMethod(this, 'initialize');
},
dispose: function()
{
ChildControl.callBaseMethod(this, 'dispose');
}
}
E sul lato dello script voglio chiamare un metodo sul controllo figlio:
ParentControl.prototype =
{
initialize: function()
{
this._childControl = $get(this._childControlID);
this._childControl.CallMethod();
ParentControl.callBaseMethod(this, 'initialize');
},
dispose: function()
{
ParentControl.callBaseMethod(this, 'dispose');
}
}
Il problema è che ogni volta che provo questo dice che questo metodo non è stato trovato o supportato. Tutti i metodi su ChildControl non dovrebbero essere accessibili da ParentControl?
Esiste un modo per rendere pubblico il metodo in modo che ParentControl possa vederlo?
Aggiorna Sarebbe possibile " digitare " the this._childControl?
Ecco il motivo per cui chiedo ... Quando uso Watch, il sistema sa qual è la classe ChildControl e posso richiamare i metodi dalla classe stessa, tuttavia non posso chiamare gli stessi metodi da this._childControl oggetto. Penseresti che se il design della classe (?) In memoria riconosce il metodo esistente e anche l'oggetto creato da quella classe lo farebbe.
Soluzione
Sul client, stai usando un campo dell'oggetto di controllo principale chiamato _childControlID passandolo in $ get. Ci sono alcuni problemi con questo:
- Come è stato impostato _childControlID? Immagino che aggiungendolo come proprietà nel descrittore del controllo parent sul server, ma non mostri quel codice e non mostri una proprietà nella classe di controllo parent sul lato client.
- $ get restituisce riferimenti ad elementi - non controlli. Quindi, anche se _childControlID è stato impostato su un ID elemento valido, quell'elemento non avrà un metodo chiamato CallMethod. Se la classe di controllo figlio sul lato client è stata inizializzata prima del controllo padre, l'elemento avrà un campo chiamato "controllo". che puoi utilizzare per accedere al controllo dello script che " allegato " stesso all'elemento. Questo funziona solo se il controllo figlio inizializzato prima del controllo principale, ovviamente.
Altri suggerimenti
Il problema è il "questo." Questo, in javaScript, si riferisce all'oggetto DOM. Devi fare qualcosa di simile a quello che succede quando usi Function.createDelegate, che è richiesto quando usi $ addHandler (che so che non stai usando, solo dando un contesto).
Hai un paio di opzioni.
-
È possibile trovare il controllo degli script figlio utilizzando $ find () . Ma corri il rischio che il controllo dei tuoi genitori venga inizializzato prima del controllo figlio.
this._childControl = $find(this._childControlID); this._childControl.CallMethod();
-
Puoi registrare una proprietà nel tuo descrittore di controllo sul server usando AddComponentProperty () . Ciò assicurerà che tutti i controlli figlio siano inizializzati prima che il controllo padre sia inizializzato.
public class CustomControl : WebControl, IScriptControl { public ScriptControl ChildControl { get; set; } public IEnumerable<ScriptDescriptor> GetScriptDescriptors() { var descriptor = new ScriptControlDescriptor("Namespace.MyCustomControl", this.ClientID); descriptor.AddComponentProperty("childControl", ChildControl.ClientID); return new ScriptDescriptor[] { descriptor }; } public IEnumerable<ScriptReference> GetScriptReferences() { var reference = new ScriptReference { Assembly = this.GetType().Assembly.FullName, Name = "MyCustomControl.js" }; return new ScriptReference[] { reference }; } }
Quindi, finché crei una proprietà lato client " childControl " verrà automaticamente inizializzato e pronto per l'uso nel metodo init () dei controlli parent.