可能的错误 - 在 widget.set('options', []) 之后触发事件更改

Possible bug - Event change fires after widget.set('options', [])

目前我正在使用 dijit/form/Select 显示选项列表,我需要以编程方式更新 dijit/form/Select.

的内容

目前我正在使用 .set('value', ...);,但我注意到事件 change 被触发(在我的情况下是不需要的)。

我需要能够在不触发 change 事件的情况下更新小部件并选择一个值。

change 事件,据我所知,只有当用户 "change" 单击 Select 列表的值时才会触发它。

require(["dijit/form/Select",
  "dojo/data/ObjectStore",
  "dojo/store/Memory",
  "dojo/domReady!"
], function(Select) {

  var options = [{
    label: "TN",
    value: "Tennessee"
  }, {
    label: "VA",
    value: "Virginia",
    selected: true
  }, {
    label: "WA",
    value: "Washington"
  }, {
    label: "FL",
    value: "Florida"
  }, {
    label: "CA",
    value: "California"
  }];

  var s = new Select({
    options: options
  }, "target");
  s.startup();

  s.on("change", function() {
    console.log("my value: " + s.get("value"))
  });

  // updating options
  options.push({
    label: "MI",
    value: "Milan",
    selected: true
  });
  s.set('options', options);
  s.reset();
  // issue here, the following line trigger event change
  s.set('value', 'mi');

})
<link href="//ajax.googleapis.com/ajax/libs/dojo/1.10.0/dijit/themes/claro/claro.css" rel="stylesheet" />
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<body class="claro">
<div id="target"></div>
</body>

_setValueAttr 还有第二个参数 - priorityChange。如果将其设置为 false,将不会触发 onChange 事件。

来自 API docs 版本 1.6(请参阅方法中的 _setValueAttr):

_setValueAttr
Overrides dijit.form._FormValueWidget, dijit.form._FormSelectWidget
Sets the value of the widget. If the value has changed, then fire onChange event, unless priorityChange is specified as null (or false?)

顺便说一句。如果您想添加一个选项,则无需替换整套选项 - 您可以调用 s.addOption(newOption)

require(["dijit/form/Select",
  "dojo/data/ObjectStore",
  "dojo/store/Memory",
  "dojo/domReady!"
], function(Select) {

  var options = [{
    label: "TN",
    value: "Tennessee"
  }, {
    label: "VA",
    value: "Virginia",
    selected: true
  }, {
    label: "WA",
    value: "Washington"
  }, {
    label: "FL",
    value: "Florida"
  }, {
    label: "CA",
    value: "California"
  }];

  var s = new Select({
    options: options
  }, "target");
  s.startup();

  s.on("change", function() {
    console.log("my value: " + s.get("value"))
  });

  // updating options
  options.push({
    label: "MI",
    value: "Milan",
    selected: true
  });
  s.set('options', options);
  s.reset();
  // issue here, the following line trigger event change
  s.set('value', 'Milan', false);

})
<link href="//ajax.googleapis.com/ajax/libs/dojo/1.10.0/dijit/themes/claro/claro.css" rel="stylesheet" />
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<body class="claro">
<div id="target"></div>
</body>

我找到了解决此问题的方法:

  myWidget.set('_onChangeActive', false); // prevent firing change
  myWidget.set('value', 'Milan', false);
  myWidget.set('_onChangeActive', true); // reset to default

在多个小部件上连续使用 .set() 时也有效。

如果您一次只更改一个小部件,也可以将 false 作为第三个参数传递给 .set()

s.set('value', 'Milan', false);

注意:我无法在官方文档中找到第三个参数的参考资料 .set():

相关问题: Dojo Select onChange event firing when changing value programatically

require(["dijit/form/Select",
  "dojo/data/ObjectStore",
  "dojo/store/Memory",
  "dojo/domReady!"
], function(Select) {

  var options = [{
    label: "TN",
    value: "Tennessee"
  }, {
    label: "VA",
    value: "Virginia",
    selected: true
  }, {
    label: "WA",
    value: "Washington"
  }, {
    label: "FL",
    value: "Florida"
  }, {
    label: "CA",
    value: "California"
  }];

  var s = new Select({
    options: options
  }, "target");
  s.startup();

  s.on("change", function() {
    console.log("my value: " + s.get("value"))
  });

  // updating options
  options.push({
    label: "MI",
    value: "Milan",
    selected: true
  });

  s.set('options', options);
  s.reset();

  s.set('_onChangeActive', false); // prevent firing change
  s.set('value', 'Milan', false);
  s.set('_onChangeActive', true);

})
<link href="//ajax.googleapis.com/ajax/libs/dojo/1.10.0/dijit/themes/claro/claro.css" rel="stylesheet" />
<script src="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dojo/dojo.js"></script>
<body class="claro">
<div id="target"></div>
</body>