Kaynağa Gözat

support static default option in <select> with options param (close #1103)

Evan You 11 yıl önce
ebeveyn
işleme
68ca56425c

+ 19 - 2
src/directives/model/select.js

@@ -43,6 +43,12 @@ module.exports = {
   update: function (value) {
     var el = this.el
     el.selectedIndex = -1
+    if (!value) {
+      if (this.defaultOption) {
+        this.defaultOption.selected = true
+      }
+      return
+    }
     var multi = this.multiple && _.isArray(value)
     var options = el.options
     var i = options.length
@@ -75,11 +81,22 @@ module.exports = {
 
 function initOptions (expression) {
   var self = this
+  var el = self.el
+  var defaultOption = self.defaultOption = self.el.options[0]
   var descriptor = dirParser.parse(expression)[0]
   function optionUpdateWatcher (value) {
     if (_.isArray(value)) {
-      self.el.innerHTML = ''
-      buildOptions(self.el, value)
+      // clear old options.
+      // cannot reset innerHTML here because IE family get
+      // confused during compilation.
+      var i = el.options.length
+      while (i--) {
+        var option = el.options[i]
+        if (option !== defaultOption) {
+          el.removeChild(option)
+        }
+      }
+      buildOptions(el, value)
       self.forceUpdate()
     } else {
       process.env.NODE_ENV !== 'production' && _.warn(

+ 30 - 2
test/unit/specs/directives/model_spec.js

@@ -369,11 +369,39 @@ if (_.inBrowser) {
         template: '<select v-model="test" options="opts | aFilter"></select>'
       })
       expect(el.firstChild.innerHTML).toBe(
-          '<option value="a0">a0</option>' +
-          '<option value="b1">b1</option>'
+        '<option value="a0">a0</option>' +
+        '<option value="b1">b1</option>'
       )
     })
 
+    it('select + options + static option', function (done) {
+      var vm = new Vue({
+        el: el,
+        data: {
+          opts: ['a', 'b']
+        },
+        template:
+          '<select v-model="test" options="opts">' +
+            '<option value="">default...</option>' +
+          '</select>'
+      })
+      expect(el.firstChild.innerHTML).toBe(
+        '<option value="">default...</option>' +
+        '<option value="a">a</option>' +
+        '<option value="b">b</option>'
+      )
+      expect(el.firstChild.options[0].selected).toBe(true)
+      vm.opts = ['c']
+      _.nextTick(function () {
+        expect(el.firstChild.innerHTML).toBe(
+          '<option value="">default...</option>' +
+          '<option value="c">c</option>'
+        )
+        expect(el.firstChild.options[0].selected).toBe(true)
+        done()
+      })
+    })
+
     it('text', function (done) {
       var vm = new Vue({
         el: el,