ASP.Net ScriptControl - Вызов одного метода из другого
-
03-07-2019 - |
Вопрос
Допустим, у меня есть два элемента управления скриптом, и один элемент управления имеет другой в качестве дочернего элемента управления:
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 .С этим связано несколько проблем:
- Как был установлен _childControlID?Я бы предположил, добавив его как свойство в дескриптор родительского элемента управления на сервере, но вы не показываете этот код и не показываете свойство в классе родительского элемента управления на стороне клиента.
- $get возвращает ссылки на элементы, а не элементы управления.Таким образом, даже если для _childControlID был установлен допустимый идентификатор элемента, у этого элемента не будет метода с именем callMethod .Если дочерний класс управления на стороне клиента инициализировался до родительского элемента управления, элемент будет иметь поле с именем "control", которое вы можете использовать для доступа к элементу управления script, который "прикрепил" себя к элементу.Конечно, это работает только в том случае, если дочерний элемент управления инициализирован раньше родительского.
Другие советы
Проблема заключается в "этом". Это в JavaScript относится к объекту DOM.Вам нужно сделать что-то похожее на то, что происходит при использовании Function.CreateDelegate , что требуется при использовании $AddHandler (который, я знаю, вы не используете, просто даете контекст).
У вас есть пара вариантов.
Вы можете найти свой дочерний элемент управления сценарием, используя $найти().Но вы рискуете, что ваш родительский элемент управления будет инициализирован раньше дочернего.
this._childControl = $find(this._childControlID); this._childControl.CallMethod();
Вы можете зарегистрировать свойство в своем управляющем дескрипторе на сервере, используя 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().