使用 Mithril.js,如何将异步函数给出的选项添加到先前添加的 select 元素
Using Mithril.js, how can I add options given by an async function, to a previously added select element
我正在尝试向先前创建的 Vnode(select 元素)添加选项。
在选项可用之前返回元素,因为它们来自异步函数。
尽管我尝试在回调时设置子元素,但这并没有改变呈现的元素。 select 元素中不显示选项。
我的代码如下:
const getSelect = function (field: FieldDef, key: string) {
const elem = m('div', { class: 'field' }, [
m('label', { class: 'label' }, field.label ? field.label : field.name),
m(
'div',
{
class: field.controlClass
? 'select ' + field.controlClass
: 'select is-small',
onchange: (val: number | string) => {
console.log(val);
},
},
[
m(
'select',
{
class: field.class ? field.class : '',
name: field.name ? field.name : key,
id: key,
value: field.value,
},
[],
),
],
),
]);
if (field.options) {
void field.options().then(function (items) {
elem.children = [];
elem.children.push(
items.map((i) => {
return m('option', { value: i.value }, i.text);
}),
);
console.log('the options are:');
console.log(elem.children);
});
}
return elem;
};
您的代码混合使用 expressions and statements 来描述视图:自 2013 年以来,Mithril 和大多数 Javascript 视图库都试图将其分开。解决方案是通过从模型中插入值来专门将视图描述为表达式,必要时可以通过视图外部的语句更改这些值。
您的代码示例无法运行的原因是无法操纵 vnode:相反,必须生成包含适当数据的新 vnode。
解决办法是:
- 动态数据模型
- 为任何动态值引用模型的视图表达式
- 可以更改模型值并指示视图重新计算的控制代码
在下面的代码中,我用一个 select 元素来近似你的问题案例,其选项稍后会改变。为了简化此示例,异步更改来自用户与视图的交互——而不是代码中的承诺——但原则保持不变:接收新选项的代码,无论它是什么,都会更改模型并指示m.redraw
的视图;当视图重绘时,它从模型中插入它的持久引用,接收一个新值,并将更改持久化到 DOM.
// 1. A dynamic data model
const model = {
options: [],
}
m.mount(document.body, {
// 2. A view expression that references the model for any dynamic values
view: () => [
m('select',
model.options.map(value =>
m('option', value),
),
),
m('hr'),
m('button', {
onclick : populate,
},
'Populate'
),
m('button', {
onclick : reset,
},
'Reset'
),
],
})
// 3. Control code which can change the model values and instruct the view to recompute
function populate(){
model.options = [1, 2, 3]
m.redraw()
}
function reset(){
model.options = []
m.redraw()
}
<script src="https://unpkg.com/mithril@2.0.4/mithril.min.js"></script>
我正在尝试向先前创建的 Vnode(select 元素)添加选项。 在选项可用之前返回元素,因为它们来自异步函数。
尽管我尝试在回调时设置子元素,但这并没有改变呈现的元素。 select 元素中不显示选项。
我的代码如下:
const getSelect = function (field: FieldDef, key: string) {
const elem = m('div', { class: 'field' }, [
m('label', { class: 'label' }, field.label ? field.label : field.name),
m(
'div',
{
class: field.controlClass
? 'select ' + field.controlClass
: 'select is-small',
onchange: (val: number | string) => {
console.log(val);
},
},
[
m(
'select',
{
class: field.class ? field.class : '',
name: field.name ? field.name : key,
id: key,
value: field.value,
},
[],
),
],
),
]);
if (field.options) {
void field.options().then(function (items) {
elem.children = [];
elem.children.push(
items.map((i) => {
return m('option', { value: i.value }, i.text);
}),
);
console.log('the options are:');
console.log(elem.children);
});
}
return elem;
};
您的代码混合使用 expressions and statements 来描述视图:自 2013 年以来,Mithril 和大多数 Javascript 视图库都试图将其分开。解决方案是通过从模型中插入值来专门将视图描述为表达式,必要时可以通过视图外部的语句更改这些值。
您的代码示例无法运行的原因是无法操纵 vnode:相反,必须生成包含适当数据的新 vnode。
解决办法是:
- 动态数据模型
- 为任何动态值引用模型的视图表达式
- 可以更改模型值并指示视图重新计算的控制代码
在下面的代码中,我用一个 select 元素来近似你的问题案例,其选项稍后会改变。为了简化此示例,异步更改来自用户与视图的交互——而不是代码中的承诺——但原则保持不变:接收新选项的代码,无论它是什么,都会更改模型并指示m.redraw
的视图;当视图重绘时,它从模型中插入它的持久引用,接收一个新值,并将更改持久化到 DOM.
// 1. A dynamic data model
const model = {
options: [],
}
m.mount(document.body, {
// 2. A view expression that references the model for any dynamic values
view: () => [
m('select',
model.options.map(value =>
m('option', value),
),
),
m('hr'),
m('button', {
onclick : populate,
},
'Populate'
),
m('button', {
onclick : reset,
},
'Reset'
),
],
})
// 3. Control code which can change the model values and instruct the view to recompute
function populate(){
model.options = [1, 2, 3]
m.redraw()
}
function reset(){
model.options = []
m.redraw()
}
<script src="https://unpkg.com/mithril@2.0.4/mithril.min.js"></script>