零、核心协作链路
1.用例触发输入 :用例创建 Input
实例,调用 input()
方法;有新项目了,管理层要指挥人干活
2.Input 调度适配 :Input
通过 get_app_input()
识别应用为 "hsy",创建 HsyInput
实例;管理层看了一下员工是A类的,那就让他以A类的标准去完成这个活。
3.HsyInput 匹配控件:
HsyInput.getInputCtrl()
识别场景为 "表单输入",调用 CtrlManager.getCtrl(ctrl_html, parent)
;员工A看了一下具体什么活,就去找零件仓库管理员拿对应这个活需要的零件。
CtrlManager
遍历注册控件,匹配到 FormComp
(因 ctrl_html
含表单特征),返回 FormComp
实例;仓库管理员找遍仓库,给到员工A这个活需要的具体零件
4. FormComp 执行输入 :HsyInput
调用 FormComp.input(value)
,FormComp
继承 InputCtrlBase
的通用逻辑,同时执行表单校验;员工A使用这个零件干活,这个零件是符合老板InputCtrlBase
的规定的,很安全可以放心使用。
返回结果 :输入完成后,HsyInput
将 FormComp
的执行结果返回给用例。员工A把干完活得到的成果给到了新项目(测试用例中有输入动作的部分)去使用。
- 最基本的:老板,【管理层,工人(分类)】,仓库管理员,零件。
- 工人继承管理层(管理人员和工人都是员工,当然和老板不一样,但是管理人员是父类,是上级)
- 零件继承老板,因为零件是依照老板的规矩定制的。
学习时,从 "用例调用流程" 反向推导,先看 Input.py
的调度逻辑,再深入 HsyInput
的具体实现,最后补全 InputCtrlBase
的抽象规范,就能彻底打通输入控件的设计思路!

1. InputCtrlBase.py
:输入控件的 "抽象接口"(规矩制定者)
- 定位 :所有输入控件的基类 / 接口 ,定义输入操作的 "标准动作"(如
input
、text
),强制子类实现。 - 核心作用 :
- 规定输入控件必须有
input
(执行输入)、text
(获取值)等方法,确保所有输入控件 "接口统一"; - 封装输入场景的通用逻辑(如输入值适配、弹窗处理),子类继承后直接复用,无需重复编码。
- 规定输入控件必须有
- 类比 :手机的 "Type-C 接口标准"------ 规定了充电、传数据的统一方式,所有充电头 / 线必须遵守。干活人该干什么,活干完达成什么目标。
2. Input.py
:输入操作的 "调度中心"(指挥官)
- 定位 :不直接执行输入,而是根据 "应用类型""输入参数" 动态选择具体的输入实现 (如
HsyInput
或TcH5Input
)。 - 核心作用 :
- 接收输入参数(输入值、类型、期望值等),集中管理;
- 通过
get_app_input()
判断当前应用(如hsy
、TcH5
),创建对应的HsyInput
/TcH5Input
实例; - 对外提供统一的
input
方法,屏蔽 "不同应用输入逻辑差异",让用例只需调用Input().input(...)
。
- 类比 :"充电线 + 智能识别芯片"------ 插入手机后,自动识别设备类型(安卓 /iOS),调度对应的充电协议。把目标细化,不同的有不同的处理方式。根据谁是什么人,活有不同的干法,使得最终都达成想要目标的结果。
3. HsyInput.py
:hsy
应用的 "输入执行者"(hsy 充电头)
- 定位 :继承
Input
类,专门处理hsy
应用(如好会计)的输入逻辑。 - 核心作用 :
- 根据
inputType
(输入类型:直接输入、扫码、参照输入等)和页面ctrl_html
(HTML 特征),匹配具体的输入控件(如文本框、扫码组件、参照选择器); - 调用
getInputCtrl
找到控件后,执行实际输入操作(如InputComp.input()
输入文本、ScanInputComp.input()
扫码)。
- 根据
- 类比 :"安卓充电头"------ 识别到安卓手机后,启动安卓充电协议,执行充电。干活人A具体如何达成这个目标。
4. TcH5Input.py
:TcH5
应用的 "输入执行者"(TcH5 充电头)
- 定位 :和
HsyInput
平级,专门处理TcH5
应用的输入逻辑(代码未贴,但逻辑对称)。 - 核心作用 :
- 根据
TcH5
应用的页面特征(HTML 结构、控件类名),匹配对应的输入控件; - 执行
TcH5
场景下的输入操作(如 H5 页面的文本输入、下拉选择)。
- 根据
- 类比 :"iOS 充电头"------ 识别到苹果手机后,启动 Lightning 充电协议,执行充电。干活人B具体如何达成这个目标。
一、工人
(1)第一步,把管理层给的要点完全记下来,不遗漏,不自创。
python
def __init__(self, inputType=None, expect=None, value=None, ctrl=None, data=None, fuzzySearch=None):
self.inputType = inputType # 输入类型(如直接输入、参照输入)
self.expect = expect if expect is not None else value # 期望值
self.data = value if data is None else data # 新页面参数
self.value = value # 输入值
self.fuzzySearch = fuzzySearch # 模糊搜索参数
self.ctrl = ctrl # 关联的具体控件实例(后续会通过 getInputCtrl 找到)
- 与
Input
基类的__init__
完全一致,目的是 "无缝接收基类传递的所有输入参数",确保参数在 "调度中心→执行者" 之间完整传递。 - 没有新增参数,说明
HsyInput
专注于 "执行" 而非 "参数管理",符合单一职责原则。
(2)根据这些要点,经常干的活自己就知道零件在哪直接拿出来用,有些零件不知道具体该用啥就要去让仓库管理员在仓库给他找。
这是 HsyInput
最关键的方法,"根据输入类型(inputType
)和页面 HTML(ctrl_html
)特征,自动匹配并返回对应的具体输入控件实例"(如文本框控件、扫码控件),解决 "不同输入场景需要不同控件" 的问题。
python
def getInputCtrl(self, parent=None, ctrl_html=None):
# 1. 匹配"直接输入"场景(最常用的文本输入)
if ((self.inputType is None ...
# 普通文本输入框,返回 InputComp 控件
return InputComp.instance(parent)
# 2. 匹配"区间输入"场景(如日期区间、金额区间)
elif self.inputType == InputType.区间输入:
return BetweenInputCtrl.instance(parent)
# 3. 匹配"扫码输入"场景(通用扫码)
elif self.inputType == InputType.扫码输入:
return ScanInputComp.instance(parent)
...
# 其他场景:由控件管理器自动匹配
else:
return CtrlManager.getCtrl(ctrl_html, parent)
# 所有条件都不匹配,抛出异常
raise Exception("没有找到输入控件")
设计亮点:
-
"输入类型 + HTML 特征" 双重判断 :
不仅根据
inputType
匹配(如InputType.扫码输入
对应ScanInputComp
),还结合ctrl_html
(控件 HTML 源码)的特征(如'input' in ctrl_html
说明是文本框,'Select-arrow-zone'
说明是下拉参照),确保匹配的控件准确无误。 -
优先级处理 :
"直接输入" 场景放在最前面,因为它是最常用的场景;特殊场景(如带下拉箭头的输入框)做单独判断,避免误判为普通文本框。
-
单例模式(
instance(parent)
) :所有控件通过
instance(parent)
获取实例(而非直接__init__
),确保每个控件在同一父容器下只有一个实例,避免重复创建,节省资源。控件和父容器绑定,控件有了上下文,驱动,就像不同的零件在不同的机械中发挥恰当的作用。 -
控件管理器(
CtrlManager
)兜底 :复杂场景(如
InputType.参照输入
)由CtrlManager
统一管理,减少HsyInput
的代码冗余,符合 "单一职责" 原则。
(3)拿零件回来了,回到工位开始忙活。
在找到具体控件(self.ctrl
)后,input
方法负责 "调用控件的输入逻辑,执行实际操作,并返回最终的期望值"。
python
def input(self, parent=None, elementParent=None, ctrl_html=None, key=None):
# 1. 如果还没找到控件,调用 getInputCtrl 匹配
if self.ctrl is None:
self.ctrl = self.getInputCtrl(parent, ctrl_html)
# 2. 等待控件加载(短暂休眠,避免操作过快)
time.sleep(0.5)
# 3. 给控件绑定父容器(用于定位)
self.ctrl.elementParent = elementParent
self.ctrl.parent = parent
# 4. 处理模糊搜索场景
if self.fuzzySearch is not None:
self.ctrl.fuzzyInput(self.fuzzySearch) # 调用控件的模糊搜索方法
# 5. 普通输入场景
else:
self.ctrl.key = key # 绑定业务键(如"客户名称")
self.ctrl.real_data = None # 清空实际数据缓存
# 调用控件的 input 方法执行输入(用 data 或 value 作为输入值)
expect = self.ctrl.input(self.value if self.data is None else self.data)
time.sleep(0.5) # 等待输入完成
# 6. 更新期望值(如果控件返回了实际结果,以实际结果为准)
if expect:
self.expect = None # 控件已处理期望,这里置空
if self.ctrl.real_data: # 控件有实际输入的数据(如参照选择后返回的ID)
self.expect = self.ctrl.real_data # 用实际数据更新期望值
# 7. 返回最终的期望值和控件实例(供后续断言或操作)
return self.expect, self.ctrl
关键逻辑:
- 控件绑定父容器 :
elementParent
和parent
是控件的定位上下文(如父页面、父组件),确保控件能正确找到页面元素。 - 模糊搜索与普通输入分离 :模糊搜索调用
fuzzyInput
方法,普通输入调用input
方法,逻辑清晰。 - 期望值动态更新 :输入后如果控件返回了
real_data
(如参照选择后实际选中的 ID,而非显示的名称),则用real_data
作为最终期望值,确保断言准确。
(4)忙活完了把成果返回给管理层Input,管理层再给到项目(用例)
对应测试用例的一行代码调用。
二、管理员
一、核心功能:集中信息;抽象目标拆解为实际目标;智慧用人。
python
def __init__(self, inputType=None, expect=None, value=None, ctrl=None, data=None, fuzzySearch=None) -> None:
self.inputType = inputType # 输入类型(如直接输入、扫码输入,对应 InputType 枚举)
self.expect = expect if expect is not None else value # 输入后的期望值(默认等于输入值)
self.data = value if data is None else data # 新页面需要的参数(如跳转后页面的初始化数据)
self.value = value # 实际输入的值(如文本框中要输入的内容)
self.fuzzySearch = fuzzySearch # 模糊搜索参数(如 {"模糊搜索": True, "具体匹配": "关键词"})
self.ctrl = ctrl # 关联的控件实例(如输入框控件,用于定位具体元素)
self.input_obj = None # 实际执行输入的对象(HsyInput 或 TcH5Input,延迟初始化)
- 如果目标是普通输入,类的实例化对象就是 Input(inputType,parent)
- 如果目标是字典输入,类的实例化就先调用Input类方法buildInput,这个类方法处理字典为data参数,放在实例化函数中,再进行实例化。
⭐ get_app_input
方法:根据应用类型适配具体输入对象 根据集中的信息智慧用人
python
def get_app_input(self):
from script.common.AppInput.HsyInput import HsyInput
from script.common.AppInput.TcH5Input import TcH5Input
# 根据当前运行的应用(从上下文获取)选择对应的输入实现类
if RunContext.getRunContext().app in ['ydz','hsy', 'cc', 'zhijia', 'hkj', 'xsc', 'retail']:
self.input_obj = HsyInput(...) # 适配"好会计"等应用的输入逻辑
elif RunContext.getRunContext().app in ['TcH5']:
self.input_obj = TcH5Input(...) # 适配"TcH5"应用的输入逻辑
else:
raise Exception("没有找到输入控件")
return self.input_obj
⭐ input
方法:统一的输入执行入口 放眼整体,这个项目好不好确实看的是管理层(部门领导)做的咋样。
python
def input(self, parent=None, elementParent=None, ctrl_html=None, key=None):
return self.get_app_input().input(parent, elementParent, ctrl_html, key)
- 作用 :对外提供统一的
input
方法,内部调用具体输入对象(HsyInput
或TcH5Input
)的input
方法执行实际输入。 - 优势 :用例无需关心 "当前应用需要调用哪个输入类",只需调用
Input().input(...)
即可,屏蔽了应用差异。
⭐ buildInput
静态方法:从字典数据构建 Input
实例 好的leader是啥抽象目标来了都能接住分析整理好成可执行的目标。
python
@staticmethod
def buildInput(data):
inputType = data[Keys.输入方式] if Keys.输入方式 in data else None
expect = data[Keys.期望值] if Keys.期望值 in data else None
fuzzySearch = {"模糊搜索":data[Keys.模糊搜索],"具体匹配":data[Keys.具体匹配]} if Keys.模糊搜索 in data else None
data = data[Keys.输入值] if Keys.输入值 in data else None
return Input(inputType=inputType, expect=expect, data=data, fuzzySearch=fuzzySearch)
- 作用 :快速将 "字典格式的输入配置"(如测试用例中的 JSON 数据)转换为
Input
实例,简化用例编写。 - 场景 :测试用例可能用字典定义输入(如
{"输入方式": "参照输入", "输入值": "张三", "期望值": "张三"}
),通过buildInput
直接转换成可执行的Input
对象。
二、相关枚举类:规范输入场景的 "常量定义"
枚举类(InputType
、ExpectType
、confirmAction
)的核心作用是 "用常量替代硬编码字符串",避免拼写错误,同时让代码更易读、易维护。
1. InputType
:定义所有支持的输入方式
python
class InputType(Enum):
直接输入 = None # 普通文本输入(如 input 标签的键盘输入)
扫码输入 = "扫码输入" # 扫码枪输入(如商品条码扫描)
商品条码输入 = "商品条码输入" # 专门针对商品条码的输入
参照输入 = "参照输入" # 从参照列表选择(如下拉框选择客户)
参照新增 = "参照新增" # 从参照列表新增选项(如新增客户后选择)
区间输入 = "区间输入" # 输入范围(如日期区间、金额区间)
好会计页面新增 = "好会计页面新增" # 好会计应用的页面内新增操作
批量修改为 = "批量修改为" # 批量修改多个元素的值
打开参照 = "打开参照" # 仅打开参照列表,不选择具体值
- 作用 :明确框架支持的所有输入方式,用例通过
InputType.直接输入
引用,比直接写字符串None
更清晰,且 IDE 会提示补全,减少错误。
2. ExpectType
:定义输入后的期望结果类型
python
class ExpectType(Enum):
提示框 = "提示框" # 输入后弹出提示(如"输入成功")
弹窗 = "弹窗" # 输入后弹出新窗口(如选择客户的弹窗)
- 作用 :配合
Input
的expect
属性,明确输入后需要验证的结果类型(是提示框还是弹窗),后续由_handleConfirmExpect
方法处理。
⭐ 整体设计逻辑:"门面模式" 简化输入操作
Input
类的设计采用了 "门面模式" (Facade Pattern)------ 对外提供一个简单统一的接口(input
方法),内部协调复杂的子系统(HsyInput
、TcH5Input
等具体实现),让用例无需了解底层细节。
用例视角:调用流程极简
python
# 1. 简单输入:直接输入文本
input_obj = Input(inputType=InputType.直接输入, value="张三")
input_obj.input(parent=page, ctrl_html=html) # 自动适配当前应用的输入逻辑
# 2. 从字典构建:适合测试用例的JSON数据
data = {"输入方式": InputType.参照输入, "输入值": "李四", "期望值": "李四"}
input_obj = Input.buildInput(data)
input_obj.input(...)
框架视角:内部逻辑清晰
- 用例调用
Input().input(...)
; Input
通过get_app_input()
确定当前应用(如 "hsy"),创建对应HsyInput
对象;- 调用
HsyInput.input(...)
执行具体输入(如参照输入的 "打开参照列表→选择选项→确认"); - 若有
expect
且包含弹窗 / 提示框,由_handleConfirmExpect
自动处理。
⭐ 核心价值总结
- 统一接口 :不管是哪种输入方式(直接输入、扫码输入)、哪个应用(hsy、TcH5),用例都用
Input().input()
调用,降低学习成本; - 场景适配 :通过
RunContext
和get_app_input
动态适配不同应用的输入逻辑,避免代码重复; - 参数集中管理 :所有输入相关参数(值、类型、期望结果)都在
Input
实例中,逻辑清晰,便于调试; - 枚举规范:用枚举替代硬编码,减少错误,提高代码可读性和可维护性。
三、仓库管理员
一、核心定位:控件的 "注册中心 + 调度中心"
想象框架中的控件(如 InputComp
、CanZaoSelectCtrl
)、弹窗(如 ConfirmBase
子类)是 "零散的零件",CtrlManager
就是 "零件仓库 + 调度员":
- 仓库 :通过
addComp
/addConfirm
等方法,将所有控件 / 弹窗 "登记入库"; - 调度员 :通过
getCtrl
/hasConfirmShow
等方法,根据页面特征(如ctrl_html
)从仓库中找到 "匹配的零件",并返回可用实例。
它的存在让框架从 "硬编码调用控件"(如 InputComp.instance(parent)
)升级为 "动态匹配控件"(如 CtrlManager.getCtrl(ctrl_html, parent)
),大幅提升扩展性。
二、核心功能:三大模块(控件管理、弹窗管理、参照控件管理)
CtrlManager
围绕 "控件" 和 "弹窗" 设计了三大核心功能,每个功能都包含 "注册" 和 "获取" 两个操作,形成闭环。
def getCtrl(cls, ctrl_html, parent):
"""
初始化具体控件,设置父组件
"""
ctrl_list = []
for comp in cls.components():
if comp.is_this_ctrl(ctrl_html):
ctrl_list.append(comp.instance(parent))
1. 业务控件管理(最核心):动态匹配输入 / 选择类控件
负责管理所有业务控件(如文本输入框、下拉选择器、参照控件),核心是 getCtrl
方法 ------ 根据页面 HTML 特征(ctrl_html
),找到并返回匹配的控件实例。
(1)关键方法拆解
方法名 | 作用 | 核心逻辑 |
---|---|---|
addComp(cls) |
向 "控件仓库" 注册控件类(如 InputComp 、CanZaoSelectCtrl ) |
将控件类(而非实例)添加到 __components 列表,供后续匹配使用。 |
components() |
获取所有已注册的控件类 | 返回 __components 列表,是 getCtrl 方法的 "数据源"。 |
getCtrl(ctrl_html, parent) |
核心!根据 ctrl_html 匹配控件,并返回实例 |
1. 遍历所有已注册的控件类; 2. 调用控件类的 is_this_ctrl(ctrl_html) 方法,判断该控件是否匹配当前 HTML 特征; 3. 收集所有匹配的控件实例,按规则返回(1 个则返回,0 个返回默认 InputComp ,多个返回第一个并报警)。 |
(2)逻辑示例(结合之前的 HsyInput
)
在 HsyInput.getInputCtrl
中,曾调用 CtrlManager.getCtrl(ctrl_html, parent)
匹配参照控件,背后逻辑是:
Matlab
# 1. 假设已注册参照控件 CanZaoSelectCtrl(通过 @register_comp 装饰器)
# 2. 当调用 CtrlManager.getCtrl(ctrl_html, parent) 时:
# a. 遍历 __components 中的所有控件类(包括 CanZaoSelectCtrl);
# b. 调用 CanZaoSelectCtrl.is_this_ctrl(ctrl_html),判断 ctrl_html 中是否有"参照控件的特征"(如 class 含"refer");
# c. 若匹配,返回 CanZaoSelectCtrl.instance(parent) 实例;
# d. 若不匹配,继续遍历其他控件,最终返回默认 InputComp。
2. 确认弹窗管理:统一检测与实例化弹窗
负责管理所有业务弹窗(如 "确认删除" 弹窗、"提示成功" 弹窗),核心是 hasConfirmShow
方法 ------ 检测当前页面是否有弹窗显示,并返回对应的弹窗实例。
关键方法拆解
方法名 | 作用 | 核心逻辑 |
---|---|---|
addConfirm(cls) |
向 "弹窗仓库" 注册弹窗类(如 DeleteConfirm 、SuccessConfirm ) |
将弹窗类添加到 __confirmModes 列表。 |
confirms() |
获取所有已注册的弹窗类 | 返回 __confirmModes 列表,是 hasConfirmShow 的 "数据源"。 |
hasConfirmShow() |
检测当前页面是否有弹窗,并返回弹窗实例 | 1. 遍历所有已注册的弹窗类; 2. 调用弹窗类的 is_show() 方法,判断弹窗是否在当前页面显示; 3. 若找到显示的弹窗,返回其实例; 4. 若未找到,返回 NoneConfirm (空弹窗实例,避免报空指针)。 |
场景价值
比如输入完成后可能弹出 "保存成功" 弹窗,用例无需硬编码判断:
python
# 无需硬编码:if DeleteConfirm.is_show(): ...
confirm = CtrlManager.hasConfirmShow() # 自动检测弹窗
if not isinstance(confirm, NoneConfirm):
confirm.click_ok() # 统一调用弹窗的"确认"方法
3. 参照控件管理:单独管理业务参照控件
负责管理 "参照选择器" 类控件(如 "选择客户""选择商品" 的参照弹窗),逻辑与 "业务控件管理" 类似,核心是 getCanZhao
方法。
方法名 | 作用 | 核心逻辑 |
---|---|---|
addCanZhao(cls) |
向 "参照控件仓库" 注册参照类(如 CustomerCanZhao 、GoodsCanZhao ) |
将参照类添加到 __canzhaos 列表。 |
canzhao_comps() |
获取所有已注册的参照类 | 返回 __canzhaos 列表。 |
getCanZhao(ctrl_html) |
根据 ctrl_html 匹配参照控件 |
遍历参照类,调用 is_this_ctrl(ctrl_html) 匹配,返回实例。 |
三、核心设计:装饰器注册 + 单例模式
CtrlManager
能实现 "低耦合、高扩展",关键依赖两个设计技巧:
单例模式就是调用的基类的instance构造实例
文件末尾的 register_comp
/register_confirm
/register_canzhao
是 装饰器 ,作用是 "让控件类在定义时自动注册到 CtrlManager
",无需手动调用 addComp
。
def register_comp(cls):
"""注册组件到CtrlManager"""
CtrlManager.addComp(cls)
return cls
例:用装饰器注册控件
python
# 以前:定义控件后,需手动调用 CtrlManager.addComp(InputComp)
# 现在:用 @register_comp 装饰器,定义时自动注册
from script.hsy.component.ctrl.CtrlManager import register_comp
@register_comp # 装饰器:自动将 InputComp 注册到 CtrlManager.__components
class InputComp(InputCtrlBase):
def is_this_ctrl(self, ctrl_html):
# 判断是否匹配当前 HTML 特征
return 'input' in ctrl_html and 'readonly' not in ctrl_html
- 新增控件时,只需加一行装饰器,无需修改
CtrlManager
或其他调用处; - 控件类与
CtrlManager
解耦(控件无需知道CtrlManager
的存在,只需被装饰即可)。
四、使用流程:从 "注册" 到 "调用" 的完整链路
以 "新增一个'商品选择控件'(GoodsSelectCtrl
)" 为例,看 CtrlManager
的完整使用流程:
⭐ 步骤 1:定义控件并注册
python
from script.hsy.component.ctrl.CtrlManager import register_comp
@register_comp # 装饰器自动注册到 CtrlManager
class GoodsSelectCtrl(InputCtrlBase):
def is_this_ctrl(self, ctrl_html):
# 定义匹配规则:HTML 中含"goods-select"类,且是下拉控件
return 'goods-select' in ctrl_html and 'Select-arrow' in ctrl_html
def input(self, value):
# 实现商品选择逻辑:点击下拉→输入商品名→选择
self.find_child(self.dropdown_loc).click()
self.find_child(self.search_loc).sendKeys(value)
self.find_child(self.option_loc.format_key(value)).click()
def getCtrl(cls, ctrl_html, parent):
"""
初始化具体控件,设置父组件
"""
ctrl_list = []
for comp in cls.components():
if comp.is_this_ctrl(ctrl_html):
ctrl_list.append(comp.instance(parent))...最终返回的是html对应所需控件类实例
即return的值为真,则把该类添加到列表。
⭐ 步骤 2:调用控件(通过 CtrlManager
)
在 HsyInput.getInputCtrl
中,无需硬编码调用 GoodsSelectCtrl
,而是通过 CtrlManager
动态匹配:
python
def getInputCtrl(self, parent, ctrl_html):
# 其他分支...
elif self.inputType == InputType.参照输入:
# 让 CtrlManager 自动匹配控件(包括刚注册的 GoodsSelectCtrl)
return CtrlManager.getCtrl(ctrl_html, parent)
# 其他分支...
⭐ 步骤 3:框架自动匹配
当页面 HTML 中出现 "商品选择控件" 的特征(goods-select
+ Select-arrow
)时:
CtrlManager.getCtrl
遍历__components
列表,找到GoodsSelectCtrl
;- 调用
GoodsSelectCtrl.is_this_ctrl(ctrl_html)
,返回True
(匹配); - 返回
GoodsSelectCtrl.instance(parent)
实例,供后续输入操作使用。