KnockoutJS + Chosen在设置后重置我的可观察值

时间:2016-12-13 19:23:32

标签: javascript knockout.js jquery-chosen

所以我正在构建这个构建ui的图表。你可以从数据库中选择字段来构建图表吗?并且图表具有刷新间隔下拉列表。

一切正常,直到我尝试从已保存的"视图"中加载一个值。 当我添加对RefreshInterval变量的订阅时,我可以看到该值设置。

但它会立即重置为我的选项数组的0&f; d。索引。

Console.log output of subscribe to RefreshInterval

[HTML]

<div class="wrapper wrapper-content" id="charts">
  <select id="interval" data-bind="options: RefreshIntervals,
    optionsText: 'Value',
    value: RefreshInterval,
    chosen: {
      disable_search_threshold: 0,
      width:'175px',
      no_results_text: 'No results!',
      placeholder_text_single: 'Select an interval',
      search_contains: true,
    }">
  </select>
</div>

[JavaScript的]

function ViewModel() {
    var self = this;
    this.RefreshIntervals = ko.observableArray([
                new Interval(0, "Never"), new Interval(10, "seconds"), new Interval(1, "minutes"), new Interval(5, "minutes")
            ]);
    this.RefreshInterval = ko.observable(new Interval(5, "minutes"));
};

var Interval = (function () {
    function Interval(length, measurement) {
    var _this = this;
    this.Length = 0;
    this.Measurement = "";
    this.Value = "";
    this.TimeoutValue = 0;
    this.GetTimeoutValue = function () {
      switch (_this.Measurement) {
        case "seconds":
          return _this.Length * 1000;
        case "minutes":
          return _this.Length * 60000;
        default:
          return 0;
      }
    };
    this.Length = length;
    this.Measurement = measurement;
    if (length == 0 || measurement == "Never") {
      this.Value = "Never";
    }
    else {
      this.Value = this.Length + " " + this.Measurement;
    }
    this.TimeoutValue = this.GetTimeoutValue();
  }
  return Interval;
}());

ko.bindingHandlers.chosen =
{
    init: function (element, valueAccessor, allBindings) {
      $(element).chosen(valueAccessor());

      // trigger chosen:updated event when the bound value or options changes

      $.each('value|selectedOptions|options'.split("|"), function (i, e) {
          var bv = allBindings.get(e);
          if (ko.isObservable(bv)) {
            bv.subscribe(function () {
              $(element).trigger('chosen:updated');
            });
          }
      });
    }
};
var vm = new ViewModel();
ko.applyBindings(vm, document.getElementById("charts"));

我在这里有一个小提琴:Fiddle

我需要填充其中3个下拉框。 我希望值是实际元素,而不是值字段,然后我需要与选项列表中的实际对象共同关联,因为选项列表可能会更改。

我有什么理由可以解决这个问题?

1 个答案:

答案 0 :(得分:1)

<select>上的值属性未正确生成 需要将optionsValue: 'Value'添加到绑定

基本上,Knockout中存在一个限制,即您无法将选定的值绑定到包装对象。

由于这种限制,编程所需的选项的唯一方法是:

vm.RefreshInterval("10 seconds");

计算的将当然返回字符串值而不是整个对象。 然后你可以简单地做到这一点来获得对象。 (或使用下划线或lodash使代码看起来更优雅)

this.RefreshInterval.subscribe(function(newValue){
 var obj = null;
 for(var i=0; i<self.RefreshIntervals().length; i++) {
   var interval = self.RefreshIntervals()[i];
   if(interval.Value === newValue) {
     obj = interval;
     break;
   }
 }
 console.log(obj);
); 

请注意,您还需要optionsValue: 'Value',

更新了working fiddle