Вопрос

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

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

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

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

Обновить Можно ли было бы "ввести" this._childControl?

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

Это было полезно?

Решение

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

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

Другие советы

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

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

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

    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", оно будет автоматически инициализировано и готово к использованию в методе parent controls init().

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top