ASP.Net ScriptControl - вызов одного метода из другого

Скажем, у меня есть два элемента управления сценарием, и один элемент управления имеет другой дочерний элемент управления:

ParentControl : ScriptControl
{
   ChildControl childControl;
}

Скрипт для Детского Контроля:

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

А на стороне скрипта я хочу вызвать метод дочернего элемента управления:

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

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

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

Проблема в том, что каждый раз, когда я пытаюсь это сказать, этот метод не найден или не поддерживается. Разве все методы в ChildControl не должны быть доступны для ParentControl?

Есть ли какой-то способ сделать метод общедоступным, чтобы ParentControl мог его увидеть?

Обновление. Будет ли возможно "напечатать" this._childControl?

Вот причина, по которой я спрашиваю... Когда я использую Watch, система знает, что такое класс ChildControl, и я могу вызывать методы самого класса, однако я не могу вызывать те же методы из объекта this._childControl. Можно подумать, что если дизайн класса (?) В памяти распознает существующий метод, и объект, созданный из этого класса, тоже будет.

3 ответа

Решение

На клиенте вы используете поле вашего родительского объекта управления _childControlID, передавая его в $ get. Есть несколько проблем с этим:

  1. Как установить _childControlID? Я бы предположил, добавив его как свойство в дескриптор родительского элемента управления на сервере, но вы не показываете этот код и не отображаете свойство в классе родительского элемента управления на стороне клиента.
  2. $ get возвращает ссылки на элементы, а не элементы управления. Таким образом, даже если для _childControlID был задан правильный идентификатор элемента, у этого элемента не будет метода CallMethod. Если класс дочернего элемента управления на стороне клиента инициализировался до родительского элемента управления, у элемента будет поле с именем "control", которое можно использовать для доступа к элементу управления сценария, который "присоединяется" к элементу. Конечно, это работает, только если дочерний элемент управления инициализирован до родительского элемента управления.

Проблема в "этом". Это в javaScript относится к объекту DOM. Вам нужно сделать что-то похожее на то, что происходит при использовании Function.createDelegate, что требуется при использовании $addHandler (который, как я знаю, вы не используете, просто задает контекст).

У вас есть пара вариантов.

  1. Вы можете найти свой дочерний элемент управления сценария с помощью $ find (). Но вы рискуете инициализировать свой родительский контроль перед дочерним контролем.

    this._childControl = $find(this._childControlID);
    this._childControl.CallMethod();
    
  2. Вы можете зарегистрировать свойство в дескрипторе элемента управления на сервере с помощью AddComponentProperty (). Это обеспечит инициализацию всех дочерних элементов управления до инициализации родительского элемента управления.

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

Затем, до тех пор, пока вы создадите клиентское свойство childControl, оно будет автоматически инициализировано и готово для использования в методе родительских элементов управления init().

Другие вопросы по тегам