秘银 - 如何从 API 填充视图的下拉列表

Mithril - how to populate drop down list of view from API

本文关键字:填充 视图 下拉列表 API 秘银      更新时间:2023-09-26

我正在尝试从其模块外部调用的方法填充由 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("element name here", ItemsList);

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

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

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

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

有没有办法实现上述目标或我应该采用的其他方法?

在对秘银的工作原理进行了更多研究之后,似乎无法调用组件中定义的任何函数。

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

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

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

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

  • mithDropDown
  • js小提琴

    var MythDropDown = function(list) {
  if (Array.isArray(list))
    this.list = list;
  else
    list = [];
  if (!(this instanceof MythDropDown))
    return new MythDropDown(list);
  var self = this;
  this.selected = {
    name: list[0],
    index: 0
  };
  this.list = list;
};
MythDropDown.prototype.view = function(ctrl) {
  var self = this;
  return m('select', {
      config: function(selectElement, isinit) {
        if (isinit)
          return;
        self.selectElement = selectElement;
        self.update(self.list);
      },
      onchange: function(e) {
        self.selected.name = e.target.value;
        self.selected.index = e.target.selectedIndex;
      }
    },
    this.list.map(function(name, i) {
      return m('option', name);
    }));
};
MythDropDown.prototype.getSelected = function() {
  return (this.selected);
};
MythDropDown.prototype.update = function(newList) {
  this.list = newList;
  this.selectElement.selectedIndex = 0;
  this.selected.name = newList[0];
  this.selected.index = 0;
};
MythDropDown.prototype.sort = function() {
  this.list.sort();
  this.update(this.list);
};
MythDropDown.prototype.delete = function() {
  this.list.splice(this.selected.index, 1);
  this.update(this.list);
};
var list = ['test option 1', 'test option 2'];
var myList = new MythDropDown(list);
var main = {
  view: function() {
    return m('.content',
      m('button', {
          onclick: function() {
            var L1 = ['Banana', 'Apple', 'Orange', 'Kiwi'];
            myList.update(L1);
          }
        },
        'Fruits'),
      m('button', {
          onclick: function() {
            var L1 = ['Yellow', 'Black', 'Orange', 'Brown', 'Red'];
            myList.update(L1);
          }
        },
        'Colors'),
      m('button', {
          onclick: function() {
            myList.sort();
          }
        },
        'Sort'),
      m('button', {
          onclick: function() {
            myList.delete();
          }
        },
        'Remove Selected'),
      m('', m.component(myList),
        m('', 'Selected Item: ' + myList.selected.name, 'Selected Index: ' + myList.selected.index)
      )
    );
  }
};
m.mount(document.body, main);
<script src="https://cdnjs.cloudflare.com/ajax/libs/mithril/0.2.3/mithril.min.js"></script>