selectize.js 和 vue.js 2 ajax 加载选项

selectize.js and vue.js 2 ajax loaded optons

我正在使用 vuejs@2.3.3,selectize@0.12.4,vue2-selectize。 我有一个相当大的表单,其中包含一些 select 输入。 所有选项都由 ajax 加载到一个 属性 中,在被 ajax 数据替换之前用演示数据初始化:

addTrackData : {

    styles : [
        { id: 1, title: 'style 1' },
        { id: 2, title: 'style 3' },
        { id: 3, title: 'style 2' },
    ],
    authors: [
        {inn: '111', name: 'demo 1'},
        {inn: '222', name: 'demo 2'},
        {inn: '333', name: 'demo 3'}
    ]
    ....
},

我有两个问题:

1) 如果我以这种方式使用设置,选项根本不会加载:

<selectize v-model="form.data.authors[i]['id']" :settings="selectize.authors"></selectize>

selectize: {
    authors: {
        valueField: 'inn',
        labelField: 'name',
        searchField: ['name', 'inn'],
        options: this.addTrackData.authors // that doesn't works, but hard coded array works
    }
} 

由于错误 Error in data(): "TypeError: Cannot read property 'authors' of undefined"this.addTrackData.authorsaddTrackData.authors 都会出现这个错误。

但这种方式有效:

<selectize v-model="form.data.authors[i]['id']"
    :settings=" {
        valueField: 'inn',
        labelField: 'name',
        searchField: ['name', 'inn'],
        options: addTrackData.authors, // It works, but looks too ugly! 
    }" >
</selectize>

2) 选项不是反应性的 - 当 ajax 数据出现时,所有 selects 元素仍然显示演示数据。而且我不知道如何更新它们...

更新

第二个问题可以通过 If Conditional 和空的初始数组来解决:

<selectize v-if="addTrackData.authors.length" v-model="form.data.authors[i]['id']"
    :settings=" {
        valueField: 'inn',
        labelField: 'name',
        searchField: ['name', 'inn'],
        options: addTrackData.authors, // It works, but looks too ugly! 
    }" >
</selectize>

addTrackData : {
    styles : [],
    authors: []
    ....
}

但是第一个问题还是让我哭了

我刚刚阅读了 vue2-selectize 的源代码,发现 options 键的手表代码不正确。

他的代码是这样的:

watch: {
  value() {
    this.setValue()
  },
  options (value, old) {
    if (this.$el.selectize && !equal(value, old)) {
      this.$el.selectize.clearOptions()
      this.$el.selectize.addOption(this.current)
      this.$el.selectize.refreshOptions(false)
      this.setValue()
    }
  }
},

虽然它应该是这样工作的:

watch: {
  value() {
    this.setValue()
  },
  options (value, old) {
    if (this.$el.selectize && !equal(value, old)) {
      this.$el.selectize.clear();
      this.$el.selectize.clearOptions();
      var vm = this;
      this.$el.selectize.load(function(callback) {
        callback(vm.current);
      });
      this.$el.selectize.refreshOptions(false);
      this.setValue();
    }
  }
},

我只是准备了一个 hacky 方法让它工作,但我不鼓励你在生产中使用它。

这是 fiddle 的 link:https://jsfiddle.net/ahmadm/h8p97hm7/

我会尽快向他的创建者发送拉取请求,但在那之前,您的解决方案已经是唯一可能的解决方案。