421
社区成员




OpenHarmony;Select;onSelect
开发板型号:
芯片:
内核版本:
OH版本:OpenHarmony 3.1 Release
问题现象:OpenHarmony 3.1 Release系统上运行ets应用,在使用Select下拉组件时,点击下拉选项无法触发onSelect回调事件
测试步骤:
通过下面的方式,可以解决此问题,在选择下拉选项的时候执行回调。基础代码如下,选择 "aaa"、"bbb"、"ccc" 时期望打印选择的inde和value值:
@Entry
@Component
struct Index {
build() {
Row() {
Column() {
Select([
{ value: "aaa" },
{ value: "bbb" },
{ value: "ccc" }
]).value('aaa')
.onSelect((index, value)=>{
console.log('onSelect index:' + index + ' value:' + value);
})
}
.width('100%')
}
.height('100%')
}
}
onSelected是API7中Select组件的选中后的事件,在API8中改为了onSelect,在这里需要使用onSelected来触发回调,修改后IDE会提示没有onSelected属性:
@Entry
@Component
struct Index {
build() {
Row() {
Column() {
Select([
{ value: "aaa" },
{ value: "bbb" },
{ value: "ccc" }
]).value('aaa')
// 这里将原先的onSelect改为onSelected
.onSelected((index, value)=>{
console.log('onSelect index:' + index + ' value:' + value);
})
}
.width('100%')
}
.height('100%')
}
}
修改\ets\3.1.5.5\component\select.d.ts 文件,复制onSelect方法,然后改名为 onSelected,此操作可以解决IDE提示报错,但是编译不会通过:
// \ets\3.1.5.5\component\select.d.ts
...
/**
* The commonMethod of select.
* @since 8
*/
declare class SelectAttribute extends CommonMethod<SelectAttribute> {
...
/**
* Callback for selecting an item from the select.
* @since 8
*/
onSelect(callback: (index: number, value?: string) => void): SelectAttribute;
// 这里将上面的 onSelect 复制后粘贴到下面 改为onSelected
/**
* Callback for selecting an item from the select.
* @since 8
*/
onSelected(callback: (index: number, value?: string) => void): SelectAttribute;
}
...
解决编译报错需要修改三个文件,分别如下:
{
"name": "Select",
"attrs": [
"selected",
"value",
"font",
"fontColor",
"selectedOptionBgColor",
"selectedOptionFont",
"selectedOptionFontColor",
"optionBgColor",
"optionFont",
"optionFontColor",
"onSelect",
// 在这里添加 onSelected
"onSelected"
]
}
{
...
"Select": {
"attrs": [
"selected",
"value",
"font",
"fontColor",
"selectedOptionBgColor",
"selectedOptionFont",
"selectedOptionFontColor",
"optionBgColor",
"optionFont",
"optionFontColor",
"onSelect",
// 在这里添加 onSelected
"onSelected"
]
},
...
}
...
/**
* The commonMethod of select.
* @since 8
*/
declare class SelectAttribute extends CommonMethod<SelectAttribute> {
/**
* Callback for selecting an item from the select.
* @since 8
*/
onSelect(callback: (index: number, value?: string) => void): SelectAttribute;
// 这里将上面的 onSelect 复制后粘贴到下面 改为onSelected
/**
* Callback for selecting an item from the select.
* @since 8
*/
onSelected(callback: (index: number, value?: string) => void): SelectAttribute;
}
...
按照以上步骤即可使用Select组件,并在其下拉选择选项时触发回调打印相关信息。
在最开始时,发现onSelect的回调函数未执行,第一猜想是代码执行出错或者代码写法有误,在打包并在设备上运行之后得出,代码编写和sdk声明都没有问题,因此查看Select的组件源码,在\foundation\ace\ace_engine\frameworks\bridge\declarative_frontend\jsview\js_select.cpp和js_select.h中发现Select定义的方法与sdk声明文件中有所差异:
// \foundation\ace\ace_engine\frameworks\bridge\declarative_frontend\jsview\js_select.cpp
// 在源码中Select组件只定义了onSelected方法,未定义onSelect方法
...
void JSSelect::JSBind(BindingTarget globalObj)
{
JSClass<JSSelect>::Declare("Select");
MethodOptions opt = MethodOptions::NONE;
JSClass<JSSelect>::StaticMethod("create", &JSSelect::Create, opt);
JSClass<JSSelect>::StaticMethod("selected", &JSSelect::Selected, opt);
JSClass<JSSelect>::StaticMethod("value", &JSSelect::Value, opt);
JSClass<JSSelect>::StaticMethod("font", &JSSelect::Font, opt);
JSClass<JSSelect>::StaticMethod("fontColor", &JSSelect::FontColor, opt);
JSClass<JSSelect>::StaticMethod("selectedOptionBgColor", &JSSelect::SelectedOptionBgColor, opt);
JSClass<JSSelect>::StaticMethod("selectedOptionFont", &JSSelect::SelectedOptionFont, opt);
JSClass<JSSelect>::StaticMethod("selectedOptionFontColor", &JSSelect::SelectedOptionFontColor, opt);
JSClass<JSSelect>::StaticMethod("optionBgColor", &JSSelect::OptionBgColor, opt);
JSClass<JSSelect>::StaticMethod("optionFont", &JSSelect::OptionFont, opt);
JSClass<JSSelect>::StaticMethod("optionFontColor", &JSSelect::OptionFontColor, opt);
// 只有onSelected
JSClass<JSSelect>::StaticMethod("onSelected", &JSSelect::OnSelected, opt);
JSClass<JSSelect>::StaticMethod("width", &JSSelect::JsWidth);
JSClass<JSSelect>::StaticMethod("height", &JSSelect::JsHeight);
JSClass<JSSelect>::StaticMethod("size", &JSSelect::JsSize);
JSClass<JSSelect>::StaticMethod("padding", &JSSelect::JsPadding);
JSClass<JSSelect>::StaticMethod("paddingTop", &JSSelect::SetPaddingTop, opt);
JSClass<JSSelect>::StaticMethod("paddingBottom", &JSSelect::SetPaddingBottom, opt);
JSClass<JSSelect>::StaticMethod("paddingLeft", &JSSelect::SetPaddingLeft, opt);
JSClass<JSSelect>::StaticMethod("paddingRight", &JSSelect::SetPaddingRight, opt);
JSClass<JSSelect>::StaticMethod("onClick", &JSInteractableView::JsOnClick);
JSClass<JSSelect>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
JSClass<JSSelect>::StaticMethod("onKeyEvent", &JSInteractableView::JsOnKey);
JSClass<JSSelect>::StaticMethod("onDeleteEvent", &JSInteractableView::JsOnDelete);
JSClass<JSSelect>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
JSClass<JSSelect>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
JSClass<JSSelect>::Inherit<JSViewAbstract>();
JSClass<JSSelect>::Bind(globalObj);
}
...
// \foundation\ace\ace_engine\frameworks\bridge\declarative_frontend\jsview\js_select.h
// js_select.h中同样只定义了onSelected方法,未定义onSelect方法
#ifndef FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_SELECT_H
#define FRAMEWORKS_BRIDGE_DECLARATIVE_FRONTEND_JS_VIEW_JS_SELECT_H
#include "frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h"
namespace OHOS::Ace::Framework {
class JSSelect : public JSViewAbstract {
public:
static void Create(const JSCallbackInfo& info);
static void JSBind(BindingTarget globalObj);
static void Selected(int value);
static void Value(const std::string& value);
static void Font(const JSCallbackInfo& info);
static void FontColor(const JSCallbackInfo& info);
static void SelectedOptionBgColor(const JSCallbackInfo& info);
static void SelectedOptionFont(const JSCallbackInfo& info);
static void SelectedOptionFontColor(const JSCallbackInfo& info);
static void OptionBgColor(const JSCallbackInfo& info);
static void OptionFont(const JSCallbackInfo& info);
static void OptionFontColor(const JSCallbackInfo& info);
// 只有 OnSelected
static void OnSelected(const JSCallbackInfo& info);
static void JsWidth(const JSCallbackInfo& info);
static void JsHeight(const JSCallbackInfo& info);
static void Width(const JSRef<JSVal>& jsValue);
static void Height(const JSRef<JSVal>& jsValue);
static void JsSize(const JSCallbackInfo& info);
static void JsPadding(const JSCallbackInfo& info);
static void SetPaddingTop(const JSCallbackInfo& info);
static void SetPaddingBottom(const JSCallbackInfo& info);
static void SetPaddingLeft(const JSCallbackInfo& info);
static void SetPaddingRight(const JSCallbackInfo& info);
};
} // namespace OHOS::Ace::Framework
#endif
由此判断出Select组件上并未有onSelect方法,因此回调函数不会执行。但是存在OnSelected方法,因此可以尝试使用OnSelected代替。
同样可以在js_select.cpp和js_select.h中将onSelected相关代码复制一份并改为onSelect也可以解决此问题。