Javascript Mithril-如何从API填充视图下拉列表

Javascript Mithril-如何从API填充视图下拉列表,javascript,google-chrome-extension,mithril.js,Javascript,Google Chrome Extension,Mithril.js,我试图从Mithril视图的模块外调用的方法(不确定这个术语是否正确,但在包含视图、模型和控制器的属性之外)填充Mithril视图呈现的下拉框 此Chrome扩展将向现有页面添加一个新字段,根据用户选择的内容,下拉框应刷新至与所选项目相关的项目。我可以进入获取新项目列表的阶段,但无法使用新对象重新绘制下拉列表 以下显示了插入到现有页面中的模块: var ItemsList = { model: function () { this.list = function (id) {

我试图从Mithril视图的模块外调用的方法(不确定这个术语是否正确,但在包含视图、模型和控制器的属性之外)填充Mithril视图呈现的下拉框

此Chrome扩展将向现有页面添加一个新字段,根据用户选择的内容,下拉框应刷新至与所选项目相关的项目。我可以进入获取新项目列表的阶段,但无法使用新对象重新绘制下拉列表

以下显示了插入到现有页面中的模块:

var ItemsList = {
  model: function () {
  this.list = function (id) {
     var d = m.deferred()
     // Calls Chrome extension bg page for retrieval of items.
     chromeExt.getItems(pId, function (items) {
       // Set default values initially when the controller is called.
       if (items.length === 0) {
         items = [
           {name: 'None', value: 'none'}
         ]
       }
       d.resolve(items || [])
     })
     return d.promise
   }
  },

  controller: function () {
    this.model = new ItemsList.model()

    this.index = m.prop(0)

    this.onchange = function (e) {
    console.info('ctrl:onchange', e.target)
    }

    // Initialise the drop down list array list.
    this.dropDownItemsList = m.prop([]);

    // This sets the default value of the drop down list to nothing by calling the function in the model, 
    // until the user selects an item which should populate the drop down list with some values.
    this.getItems = function(pId) {
      this.model.list(pId).then(function (data) {
      this.dropDownItemsList(data)
        m.redraw()
      }.bind(this))
    }

    this.getItems(0);
  },

  view: function (ctrl) {
    var SELECT_ID = 'record_select'
    return vm.Type() ? m('div', [
      m('.form__item', [
        m('.label', [
          m('label', {
            htmlFor: SELECT_ID
          }, 'ID')
        ]),
        m('.field', [
          m('select#' + SELECT_ID, {
              onchange: ctrl.onchange.bind(ctrl)
            },
            ctrl.dropDownItemsList().map(function (it, i) {
              return m('option', {
                value: it.value,
                checked: ctrl.model.index === i
              }, it.name)
            })
          ),

        ])
      ]),
    ]) : null
  }
}
它是使用
m.mount(“此处的元素名称”,ItemsList)

检查项目是否已更改的代码正在使用变异观察程序,每当它检测到某个字段的更改时,它将调用一个方法来获取新值。我可以看到返回值包含我的新项目

我尝试了各种不同的方法来更新下拉列表,首先尝试用我得到的新项目列表设置“this.list”,或者尝试在控制器上创建一个可返回的方法,当变异观察器触发时可以调用该方法

获取新项目后,如何使下拉列表显示已检索的新项目

我已经阅读了一些指南,其中显示了正在运行的控制器或模型中的函数,但前提是这些函数已经被定义为在视图中使用它们(即,视图中有一个调用该方法的onclick方法),但到目前为止,我还不知道如何从模块外部更新或调用方法


有没有一种方法可以实现上述目标,或者我应该采用另一种方法来实现这一目标?

在对Mithril的工作原理进行了更多研究之后,似乎不可能调用组件中定义的任何函数

因此,我将模型移动到组件外部(因此现在它只定义了控制器和视图),并将视图绑定到组件外部使用模型


现在调用一个更新模型的函数(现在可以从代码中的其他地方访问该函数)并重新绘制显示所需的正确值。

如果我理解正确,您需要有两个变量来存储列表,一个用于存储旧列表,另一个用于存储更新的列表,这样您可以始终映射更新的列表,并在需要时转到旧列表

下面是一个下拉列表的简单实现,其中包含一些更新和搜索的方法。您可以使用以下方法动态更新列表

var MythDropDown=函数(列表){
if(Array.isArray(列表))
this.list=列表;
其他的
列表=[];
如果(!(此实例为Mythof下拉列表))
返回新的下拉列表(列表);
var self=这个;
此。已选择={
名称:列表[0],
索引:0
};
this.list=列表;
};
MythDropDown.prototype.view=函数(ctrl){
var self=这个;
返回m('select'{
配置:函数(selectElement,isinit){
如果(isinit)
返回;
self.selectElement=selectElement;
自我更新(self.list);
},
onchange:函数(e){
self.selected.name=e.target.value;
self.selected.index=e.target.selectedIndex;
}
},
this.list.map(函数(名称,i){
返回m('选项',名称);
}));
};
MythDropDown.prototype.getSelected=函数(){
返回(此选项已选定);
};
MythDropDown.prototype.update=函数(newList){
this.list=newList;
this.selectElement.selectedIndex=0;
this.selected.name=newList[0];
this.selected.index=0;
};
MythDropDown.prototype.sort=函数(){
this.list.sort();
此.更新(此.列表);
};
MythDropDown.prototype.delete=函数(){
此.list.splice(此.selected.index,1);
此.更新(此.列表);
};
变量列表=[‘测试选项1’、‘测试选项2’];
var myList=新的神话下拉列表(列表);
var main={
视图:函数(){
返回m(“.content”,
m(‘按钮’{
onclick:function(){
变量L1=[‘香蕉’、‘苹果’、‘橘子’、‘猕猴桃’];
myList.update(L1);
}
},
"水果",,
m(‘按钮’{
onclick:function(){
变量L1=[“黄色”、“黑色”、“橙色”、“棕色”、“红色”];
myList.update(L1);
}
},
“颜色”),
m(‘按钮’{
onclick:function(){
myList.sort();
}
},
“排序”),
m(‘按钮’{
onclick:function(){
myList.delete();
}
},
“删除选定项”),
m(“”,m.组件(myList),
m(“”,“选定项:”+myList.Selected.name,“选定索引:”+myList.Selected.Index)
)
);
}
};
m、 安装(文件主体、主体)