2008-12-30 5 views
0

que j'ai deux commandes de script et un contrôle a l'autre comme un contrôle enfant:ASP.Net ScriptControl - Appel d'une méthode d'un autre

ParentControl : ScriptControl 
{ 
    ChildControl childControl; 
} 

Le script pour le contrôle des enfants:

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'); 
    } 
} 

Et sur le côté de script que je veux appeler une méthode sur le contrôle des enfants:

ParentControl.prototype = 
{ 
    initialize: function() 
    { 
     this._childControl = $get(this._childControlID); 
     this._childControl.CallMethod(); 

     ParentControl.callBaseMethod(this, 'initialize'); 
    }, 

    dispose: function() 
    { 
     ParentControl.callBaseMethod(this, 'dispose'); 
    } 
} 

le problème est, à chaque fois que je tente ce qui est dit cette méthode n'est pas trouvée ou prise en charge. Toutes les méthodes de ChildControl ne devraient-elles pas être accessibles par le ParentControl?

Existe-t-il un moyen de rendre la méthode publique afin que le contrôle ParentControl puisse la voir?

Mise à jour Serait-il possible de "taper" le this._childControl? Voici la raison pour laquelle je demande ... Lorsque j'utilise Watch, le système connaît la classe ChildControl, et je peux appeler des méthodes hors de la classe elle-même, mais je ne peux pas appeler les mêmes méthodes. Objet _childControl. On pourrait penser que si la classe design (?) En mémoire reconnaît la méthode existante, et que l'objet instancié de cette classe le serait aussi.

Répondre

1

Sur le client, vous utilisez un champ de votre objet de contrôle parent appelé _childControlID en le passant dans $ get. Il y a quelques problèmes avec ceci:

  1. Comment _childControlID a été défini? Je suppose en l'ajoutant comme une propriété dans le descripteur du contrôle parent sur le serveur, mais vous ne montrez pas ce code et vous n'affichez pas une propriété sur la classe de contrôle parent côté client.
  2. $ get renvoie les références d'éléments - et non les contrôles. Donc, même si _childControlID a été défini sur un ID d'élément valide, cet élément n'aura pas de méthode appelée CallMethod. Si la classe de contrôle enfant côté client s'est initialisée avant le contrôle parent, l'élément aura un champ appelé "contrôle" que vous pouvez utiliser pour accéder au contrôle de script qui "s'est attaché" à l'élément. Cela ne fonctionne que si le contrôle enfant est initialisé avant le contrôle parent, bien sûr.
+0

Le problème suivant est de supprimer le gestionnaire car il semble que l'enfant est supprimé avant la partie, et donc (je suppose) l'objet de contrôle de l'enfant n'exsite plus. –

1

Le problème est le "ceci". Ceci, en javaScript, fait référence à l'objet DOM. Vous devez faire quelque chose de similaire à ce qui se passe lorsque vous utilisez Function.createDelegate, ce qui est nécessaire lors de l'utilisation de $ addHandler (que je sais que vous n'utilisez pas, juste en donnant contexte).

0

Vous avez quelques options.

  1. Vous pouvez trouver votre contrôle de script enfant à l'aide $ find(). Mais vous courez le risque que votre contrôle parent soit initialisé avant le contrôle de l'enfant.

    this._childControl = $find(this._childControlID); 
    this._childControl.CallMethod(); 
    
  2. Vous pouvez enregistrer une propriété dans votre descripteur de commande sur le serveur en utilisant AddComponentProperty(). Cela s'assurera que tous les contrôles enfants sont initialisés avant l'initialisation du contrôle parent.méthode

    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 }; 
        } 
    } 
    

Ensuite, aussi longtemps que vous créez une propriété côté client « ChildControl » il sera automatiquement initialisé et prêt à être utilisé dans le contrôle parent (init).

Questions connexes