Skip to content

Commit bee8b0e

Browse files
committed
refactor: 重构代码
1 parent 877eb3f commit bee8b0e

File tree

4 files changed

+130
-96
lines changed

4 files changed

+130
-96
lines changed

src/BootstrapBlazor/Components/AutoComplete/AutoComplete.razor

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,17 @@
99
<input @attributes="AdditionalAttributes" id="@InputId" class="@ClassName" autocomplete="off" type="text"
1010
data-bs-toggle="@ToggleString" data-bs-placement="@PlacementString" data-bb-debounce="@DurationString"
1111
data-bs-offset="@OffsetString" data-bs-custom-class="@CustomClassString"
12-
data-bb-auto-dropdown-focus="@ShowDropdownListOnFocusString"
12+
data-bb-auto-dropdown-focus="@ShowDropdownListOnFocusString" data-bb-skip-esc="@SkipEscString" data-bb-skip-enter="@SkipEnterString"
13+
data-bb-scroll-behavior="@ScrollIntoViewBehaviorString"
1314
placeholder="@PlaceHolder" disabled="@Disabled" @ref="FocusElement" />
1415
<span class="form-select-append"><i class="@Icon"></i></span>
1516
<span class="form-select-append ac-loading"><i class="@LoadingIcon"></i></span>
1617
<ul class="dropdown-menu">
17-
@if (FilterItems.Any())
18+
@if (_items != null)
1819
{
19-
@foreach (var item in FilterItems)
20+
@foreach (var item in _items)
2021
{
21-
<li @key="item" class="dropdown-item" @onmousedown="() => OnClickItem(item)">
22+
<li @key="item" class="dropdown-item" @onclick="() => OnClickItem(item)">
2223
@if (ItemTemplate == null)
2324
{
2425
<div>@item</div>

src/BootstrapBlazor/Components/AutoComplete/AutoComplete.razor.cs

Lines changed: 75 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@ public partial class AutoComplete
1818
protected virtual string? ClassString => CssBuilder.Default("auto-complete")
1919
.Build();
2020

21-
/// <summary>
22-
/// 获得 最终候选数据源
23-
/// </summary>
24-
[NotNull]
25-
protected List<string>? FilterItems { get; private set; }
26-
2721
/// <summary>
2822
/// 获得/设置 通过输入字符串获得匹配数据集合
2923
/// </summary>
@@ -80,6 +74,12 @@ public partial class AutoComplete
8074
[Parameter]
8175
public bool SkipEsc { get; set; }
8276

77+
/// <summary>
78+
/// 获得/设置 滚动行为 默认 <see cref="ScrollIntoViewBehavior.Smooth"/>
79+
/// </summary>
80+
[Parameter]
81+
public ScrollIntoViewBehavior ScrollIntoViewBehavior { get; set; } = ScrollIntoViewBehavior.Smooth;
82+
8383
/// <summary>
8484
/// 获得/设置 候选项模板 默认 null
8585
/// </summary>
@@ -107,18 +107,21 @@ public partial class AutoComplete
107107

108108
private string CurrentSelectedItem { get; set; } = "";
109109

110+
private List<string>? _items;
111+
112+
private string? SkipEscString => SkipEsc ? "true" : null;
113+
114+
private string? SkipEnterString => SkipEnter ? "true" : null;
115+
116+
private string? ScrollIntoViewBehaviorString => ScrollIntoViewBehavior == ScrollIntoViewBehavior.Smooth ? null : ScrollIntoViewBehavior.ToDescriptionString();
117+
110118
/// <summary>
111119
/// <inheritdoc/>
112120
/// </summary>
113121
protected override void OnInitialized()
114122
{
115123
base.OnInitialized();
116124

117-
NoDataTip ??= Localizer[nameof(NoDataTip)];
118-
PlaceHolder ??= Localizer[nameof(PlaceHolder)];
119-
Items ??= [];
120-
FilterItems ??= [];
121-
122125
SkipRegisterEnterEscJSInvoke = true;
123126
}
124127

@@ -129,8 +132,12 @@ protected override void OnParametersSet()
129132
{
130133
base.OnParametersSet();
131134

135+
NoDataTip ??= Localizer[nameof(NoDataTip)];
136+
PlaceHolder ??= Localizer[nameof(PlaceHolder)];
132137
Icon ??= IconTheme.GetIconByKey(ComponentIcons.AutoCompleteIcon);
133138
LoadingIcon ??= IconTheme.GetIconByKey(ComponentIcons.LoadingIcon);
139+
140+
_items = Items?.ToList();
134141
}
135142

136143
/// <summary>
@@ -153,58 +160,60 @@ protected virtual async Task OnClickItem(string val)
153160
[JSInvokable]
154161
public virtual async Task OnKeyUp(string key)
155162
{
156-
var source = FilterItems;
157-
if (source.Count > 0)
158-
{
159-
// 键盘向上选择
160-
if (key == "ArrowUp")
161-
{
162-
var index = source.IndexOf(CurrentSelectedItem) - 1;
163-
if (index < 0)
164-
{
165-
index = source.Count - 1;
166-
}
167-
CurrentSelectedItem = source[index];
168-
CurrentItemIndex = index;
169-
}
170-
else if (key == "ArrowDown")
171-
{
172-
var index = source.IndexOf(CurrentSelectedItem) + 1;
173-
if (index > source.Count - 1)
174-
{
175-
index = 0;
176-
}
177-
CurrentSelectedItem = source[index];
178-
CurrentItemIndex = index;
179-
}
180-
else if (key == "Escape")
181-
{
182-
await OnBlur();
183-
if (!SkipEsc && OnEscAsync != null)
184-
{
185-
await OnEscAsync(Value);
186-
}
187-
}
188-
else if (IsEnterKey(key))
189-
{
190-
if (!string.IsNullOrEmpty(CurrentSelectedItem))
191-
{
192-
CurrentValueAsString = CurrentSelectedItem;
193-
if (OnSelectedItemChanged != null)
194-
{
195-
await OnSelectedItemChanged(CurrentSelectedItem);
196-
}
197-
}
198-
199-
await OnBlur();
200-
if (!SkipEnter && OnEnterAsync != null)
201-
{
202-
await OnEnterAsync(Value);
203-
}
204-
}
205-
}
206-
await CustomKeyUp(key);
207-
StateHasChanged();
163+
await Task.Delay(0);
164+
165+
//var source = FilterItems;
166+
//if (source.Count > 0)
167+
//{
168+
// // 键盘向上选择
169+
// if (key == "ArrowUp")
170+
// {
171+
// var index = source.IndexOf(CurrentSelectedItem) - 1;
172+
// if (index < 0)
173+
// {
174+
// index = source.Count - 1;
175+
// }
176+
// CurrentSelectedItem = source[index];
177+
// CurrentItemIndex = index;
178+
// }
179+
// else if (key == "ArrowDown")
180+
// {
181+
// var index = source.IndexOf(CurrentSelectedItem) + 1;
182+
// if (index > source.Count - 1)
183+
// {
184+
// index = 0;
185+
// }
186+
// CurrentSelectedItem = source[index];
187+
// CurrentItemIndex = index;
188+
// }
189+
// else if (key == "Escape")
190+
// {
191+
// await OnBlur();
192+
// if (!SkipEsc && OnEscAsync != null)
193+
// {
194+
// await OnEscAsync(Value);
195+
// }
196+
// }
197+
// else if (IsEnterKey(key))
198+
// {
199+
// if (!string.IsNullOrEmpty(CurrentSelectedItem))
200+
// {
201+
// CurrentValueAsString = CurrentSelectedItem;
202+
// if (OnSelectedItemChanged != null)
203+
// {
204+
// await OnSelectedItemChanged(CurrentSelectedItem);
205+
// }
206+
// }
207+
208+
// await OnBlur();
209+
// if (!SkipEnter && OnEnterAsync != null)
210+
// {
211+
// await OnEnterAsync(Value);
212+
// }
213+
// }
214+
//}
215+
//await CustomKeyUp(key);
216+
//StateHasChanged();
208217
}
209218

210219
/// <summary>
@@ -224,20 +233,20 @@ public async Task TriggerOnChange(string val)
224233
if (OnCustomFilter != null)
225234
{
226235
var items = await OnCustomFilter(val);
227-
FilterItems = items.ToList();
236+
_items = items.ToList();
228237
}
229238
else
230239
{
231240
var comparison = IgnoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
232241
var items = IsLikeMatch
233242
? Items.Where(s => s.Contains(val, comparison))
234243
: Items.Where(s => s.StartsWith(val, comparison));
235-
FilterItems = items.ToList();
244+
_items = items.ToList();
236245
}
237246

238247
if (DisplayCount != null)
239248
{
240-
FilterItems = FilterItems.Take(DisplayCount.Value).ToList();
249+
_items = _items.Take(DisplayCount.Value).ToList();
241250
}
242251

243252
CurrentValue = val;

src/BootstrapBlazor/Components/AutoComplete/AutoComplete.razor.js

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,20 @@ export function init(id, invoke) {
2020
const duration = parseInt(input.getAttribute('data-bb-debounce') || '0');
2121
if (duration > 0) {
2222
ac.debounce = true
23-
EventHandler.on(input, 'keyup', debounce(e => {
24-
invoke.invokeMethodAsync('OnKeyUp', e.code)
23+
EventHandler.on(input, 'keyup', debounce(async e => {
24+
await handlerKeyup(ac, e);
2525
}, duration, e => {
26-
return ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Escape', 'Enter', 'NumpadEnter'].indexOf(e.key) > -1
26+
return ['ArrowUp', 'ArrowDown', 'Escape', 'Enter', 'NumpadEnter'].indexOf(e.key) > -1
2727
}))
2828
}
2929
else {
30-
EventHandler.on(input, 'keyup', e => {
31-
invoke.invokeMethodAsync('OnKeyUp', e.code)
30+
EventHandler.on(input, 'keyup', async e => {
31+
await handlerKeyup(ac, e);
3232
})
3333
}
3434

3535
EventHandler.on(input, 'focus', e => {
36-
const showDropdownOnFocus = input.getAttribute('data-bb-auto-dropdown-focus') === 'true';
36+
const showDropdownOnFocus = input.getAttribute('data-bb-auto-dropdown-focus') !== 'false';
3737
if (showDropdownOnFocus) {
3838
if (ac.popover === void 0) {
3939
el.classList.add('show');
@@ -54,31 +54,55 @@ export function init(id, invoke) {
5454
});
5555
}
5656

57-
export function autoScroll(id, index) {
58-
const ac = Data.get(id)
59-
const menu = ac.menu
60-
const styles = getComputedStyle(menu)
61-
const maxHeight = parseInt(styles.maxHeight) / 2
62-
const itemHeight = getHeight(menu.querySelector('li'))
63-
const height = itemHeight * index
64-
const count = Math.floor(maxHeight / itemHeight)
65-
66-
const active = menu.querySelector('.active')
67-
if (active) {
68-
active.classList.remove('active')
57+
const handlerKeyup = async (ac, e) => {
58+
const key = e.key;
59+
const { el, input, menu, invoke } = ac;
60+
if (key === 'Enter' || key === 'NumpadEnter') {
61+
const skipEnter = el.getAttribute('data-bb-skip-enter') === 'true';
62+
if (!skipEnter) {
63+
//await invoke.invokeMethodAsync('TriggerOnChange', key);
64+
}
65+
}
66+
else if (key === 'Escape') {
67+
const skipEsc = el.getAttribute('data-bb-skip-esc') === 'true';
68+
if (!skipEsc) {
69+
input.blur();
70+
}
6971
}
72+
else if (key === 'ArrowUp' || key === 'ArrowDown') {
73+
e.preventDefault();
74+
e.stopPropagation();
7075

71-
const len = menu.children.length
72-
if (index < len) {
73-
menu.children[index].classList.add('active')
76+
const items = [...menu.querySelectorAll('.dropdown-item')];
77+
let current = menu.querySelector('.active');
78+
if (current !== null) {
79+
current.classList.remove('active');
80+
}
81+
let index = current === null ? -1 : items.indexOf(current);
82+
index = key === 'ArrowUp' ? index - 1 : index + 1;
83+
if (index < 0) {
84+
index = items.length - 1;
85+
}
86+
else if (index > items.length - 1) {
87+
index = 0;
88+
}
89+
items[index].classList.add('active');
90+
const top = getTop(menu, index);
91+
menu.scrollTo({ top: top, left: 0, behavior: 'smooth' });
7492
}
93+
}
7594

95+
const getTop = (menu, index) => {
96+
const styles = getComputedStyle(menu)
97+
const maxHeight = parseInt(styles.maxHeight) / 2
98+
const itemHeight = getHeight(menu.querySelector('.dropdown-item'))
99+
const height = itemHeight * index
100+
const count = Math.floor(maxHeight / itemHeight);
101+
let top = 0;
76102
if (height > maxHeight) {
77-
menu.scrollTop = itemHeight * (index > count ? index - count : index)
78-
}
79-
else if (index <= count) {
80-
menu.scrollTop = 0
103+
top = itemHeight * (index > count ? index - count : index)
81104
}
105+
return top;
82106
}
83107

84108
export function triggerFocus(id) {

src/BootstrapBlazor/Components/AutoComplete/PopoverCompleteBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public abstract class PopoverCompleteBase<TValue> : BootstrapInputBase<TValue>,
107107
/// <summary>
108108
/// 获得 获得焦点自动显示下拉框设置字符串
109109
/// </summary>
110-
protected string? ShowDropdownListOnFocusString => ShowDropdownListOnFocus ? "true" : null;
110+
protected string? ShowDropdownListOnFocusString => ShowDropdownListOnFocus ? null : "false";
111111

112112
/// <summary>
113113
/// 获得 CustomClass 字符串

0 commit comments

Comments
 (0)