循环正则表达式创建第二组元素
Looped RegEx creating second set of elements
我有一个填充 select 框的车把助手,我对其进行了修改,因此它可以与多项选择 select 框一起使用。虽然它现在可以成功检查多个框,但它现在使下拉菜单中的每个选项都有两组。
select: function(selected, options){
let selLength;
let newOptions;
if(Array.isArray(selected) == true){
selLength = selected.length;
let i;
for(i = 0; i < selLength; i++){
newOptions += options.fn(this).replace(new RegExp(' value=\"' + selected[i] + '\"'), '$& selected="selected"').replace(new RegExp('>' + selected[i] + '</option>'), ' selected="selected"$&');
} return newOptions
} else {
return options.fn(this).replace(new RegExp(' value=\"' + selected + '\"'), '$& selected="selected"').replace(new RegExp('>' + selected + '</option>'), ' selected="selected"$&');
}
},
这是通过以下方式调用的:
{{#select userStatus.userGroup}}
<option value="" disabled selected>Choose your option</option>
<option value="IT">IT / Development</option>
<option value="Management">Management</option>
<option value="Analyst">Analyst</option>
<option value="orderFul">Order Fulffilment</option>
<option value="QA">Quality Analyst</option>
<option value="Rep">Company Rep</option>
{{/select}}
userGroup 是一个包含用户所属组的数组。
我明白你想做什么。我对这类事情有经验,如果你花时间理解我的建议,我想你会发现它很有帮助。
您的问题不在于正则表达式。正如我在评论中指出的那样,对于 userStatus.userGroup`.
中的每个项目,您将在输出中附加整个 #select
块模板
澄清一下:在您的帮助器中您有 options.fn(this)
的地方,您可以将其视为包含模板和所有 <option>
元素的字符串。每次你做 newOptions += options.fn(this)
你只是将该块附加到你的输出;并且您对 selected
中的 每个元素 执行一次,即 userStatus.userGroup
。所以如果你在 userStatus.userGroup
中有 3 个元素,你将输出你的选项 3 次:
要修复您的助手,您需要停止向输出添加附加,而是在单个字符串实例上执行所有替换。
let selLength = selected.length;
let newOptions = options.fn(this);
let i;
for (i = 0; i < selLength; i++) {
newOptions = newOptions.replace(new RegExp(' value=\"' + selected[i] + '\"'), '$& selected="selected"').replace(new RegExp('>' + selected[i] + '</option>'), ' selected="selected"$&');
}
return newOptions;
请参阅此 fiddle 以供参考。
此代码将修复您的助手,但这是编写应用程序的糟糕方式。
模板的用途是通过数据插值和条件控制结构生成字符串输出。创建一个获取模板输出然后对该输出执行替换的帮助程序没有意义。这些替换的逻辑应该在模板的内部。
我认为更好的方法是从模板中分离数据。我建议将选项制作成您提供给模板的数据。例如:
options: [
{
label: 'IT / Development',
value: 'IT'
},
{
label: 'Management',
value: 'Management'
},
{
label: 'Analyst',
value: 'Analyst'
},
{
label: 'Order Fulfillment',
value: 'orderFul'
},
{
label: 'Quality Analyst',
value: 'QA'
},
{
label: 'Company Rep',
value: 'Rep'
}
]
并且您的模板将变得更加简单且噪音更少:
{{#each options}}
<option value="{{value}}">{{label}}</option>
{{/each}}
接下来,我们必须想办法解决在userStatus.userGroup
中可以找到的每个选项添加selected
属性的问题。为此,我们可以编写一个简单的帮助程序,它会告诉我们是否在数组中找到了某个值。这种对 helper 的使用是合法的,因为它不会操纵我们的输出,而只是 helping 我们模板的条件逻辑。下面是此类助手的一个简单示例:
Handlebars.registerHelper('contains', function (array, value) {
if (!Array.isArray(array)) { return false; }
return array.indexOf(value) > -1;
});
现在我们可以在我们的模板中使用这个助手来确定哪些 <option>
元素应该具有 selected
属性:
{{#each options}}
<option {{#if (contains ../userStatus.userGroup value)}}selected{{/if}} value="{{value}}">{{label}}</option>
{{/each}}
请参阅此 fiddle 以供参考。
我希望您能理解为什么这种方法更可取。
我有一个填充 select 框的车把助手,我对其进行了修改,因此它可以与多项选择 select 框一起使用。虽然它现在可以成功检查多个框,但它现在使下拉菜单中的每个选项都有两组。
select: function(selected, options){
let selLength;
let newOptions;
if(Array.isArray(selected) == true){
selLength = selected.length;
let i;
for(i = 0; i < selLength; i++){
newOptions += options.fn(this).replace(new RegExp(' value=\"' + selected[i] + '\"'), '$& selected="selected"').replace(new RegExp('>' + selected[i] + '</option>'), ' selected="selected"$&');
} return newOptions
} else {
return options.fn(this).replace(new RegExp(' value=\"' + selected + '\"'), '$& selected="selected"').replace(new RegExp('>' + selected + '</option>'), ' selected="selected"$&');
}
},
这是通过以下方式调用的:
{{#select userStatus.userGroup}}
<option value="" disabled selected>Choose your option</option>
<option value="IT">IT / Development</option>
<option value="Management">Management</option>
<option value="Analyst">Analyst</option>
<option value="orderFul">Order Fulffilment</option>
<option value="QA">Quality Analyst</option>
<option value="Rep">Company Rep</option>
{{/select}}
userGroup 是一个包含用户所属组的数组。
我明白你想做什么。我对这类事情有经验,如果你花时间理解我的建议,我想你会发现它很有帮助。
您的问题不在于正则表达式。正如我在评论中指出的那样,对于 userStatus.userGroup`.
中的每个项目,您将在输出中附加整个#select
块模板
澄清一下:在您的帮助器中您有 options.fn(this)
的地方,您可以将其视为包含模板和所有 <option>
元素的字符串。每次你做 newOptions += options.fn(this)
你只是将该块附加到你的输出;并且您对 selected
中的 每个元素 执行一次,即 userStatus.userGroup
。所以如果你在 userStatus.userGroup
中有 3 个元素,你将输出你的选项 3 次:
要修复您的助手,您需要停止向输出添加附加,而是在单个字符串实例上执行所有替换。
let selLength = selected.length;
let newOptions = options.fn(this);
let i;
for (i = 0; i < selLength; i++) {
newOptions = newOptions.replace(new RegExp(' value=\"' + selected[i] + '\"'), '$& selected="selected"').replace(new RegExp('>' + selected[i] + '</option>'), ' selected="selected"$&');
}
return newOptions;
请参阅此 fiddle 以供参考。
此代码将修复您的助手,但这是编写应用程序的糟糕方式。
模板的用途是通过数据插值和条件控制结构生成字符串输出。创建一个获取模板输出然后对该输出执行替换的帮助程序没有意义。这些替换的逻辑应该在模板的内部。
我认为更好的方法是从模板中分离数据。我建议将选项制作成您提供给模板的数据。例如:
options: [
{
label: 'IT / Development',
value: 'IT'
},
{
label: 'Management',
value: 'Management'
},
{
label: 'Analyst',
value: 'Analyst'
},
{
label: 'Order Fulfillment',
value: 'orderFul'
},
{
label: 'Quality Analyst',
value: 'QA'
},
{
label: 'Company Rep',
value: 'Rep'
}
]
并且您的模板将变得更加简单且噪音更少:
{{#each options}}
<option value="{{value}}">{{label}}</option>
{{/each}}
接下来,我们必须想办法解决在userStatus.userGroup
中可以找到的每个选项添加selected
属性的问题。为此,我们可以编写一个简单的帮助程序,它会告诉我们是否在数组中找到了某个值。这种对 helper 的使用是合法的,因为它不会操纵我们的输出,而只是 helping 我们模板的条件逻辑。下面是此类助手的一个简单示例:
Handlebars.registerHelper('contains', function (array, value) {
if (!Array.isArray(array)) { return false; }
return array.indexOf(value) > -1;
});
现在我们可以在我们的模板中使用这个助手来确定哪些 <option>
元素应该具有 selected
属性:
{{#each options}}
<option {{#if (contains ../userStatus.userGroup value)}}selected{{/if}} value="{{value}}">{{label}}</option>
{{/each}}
请参阅此 fiddle 以供参考。
我希望您能理解为什么这种方法更可取。