秘银 - 如何从API

时间:2016-01-16 07:10:16

标签: javascript google-chrome-extension mithril.js

我正在尝试填充Mithril视图从其模块外部调用的方法呈现的下拉框(不确定此术语是否正确,但在包含视图,模型和控制器的属性之外)。< / p>

此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方法)但到目前为止我无法弄清楚如何从模块外部更新或调用方法。

有没有办法实现上述或不同的方法我应该接近这个?

2 个答案:

答案 0 :(得分:0)

在对Mithril如何工作的更多研究之后,似乎无法调用组件中定义的任何函数。

由于这个原因,我已经将模型移到组件之外(所以现在它只有控制器和视图定义)并绑定视图以使用组件外部的模型。

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

答案 1 :(得分:0)

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

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

&#13;
&#13;
/// <summary>
/// Implements a wrapper around a .Net stream allowing it to be used with MPXJ
/// where a Java InputStream is expected.
/// This code is based on DotNetInputStream.java from the Saxon project http://www.sf.net/projects/saxon
/// Note that I've provided this class as a convenience so there are a matching pair of
/// input/output stream wrapper shopped with MPXJ. IKVM also ships with an input stream wrapper:
/// ikvm.io.InputStreamWrapper, which you could use instead of this one.
/// </summary>
&#13;
    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);
&#13;
&#13;
&#13;