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

霸气de小男生 提交于 2019-12-11 05:35:01

问题


Currently I am using dijit/form/Select to display a list of options and I need to programmatically update content for the dijit/form/Select.

Currently I am using .set('value', ...); but I have noticed that event change is fired (which is in my case is not wanted).

I need to be able to update the widget and selecting a value without having fired change event.

The change event, afaik, it should be fired only when an user "change" the value of the Select list clicking on it.

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>

回答1:


_setValueAttr has also second parameter - priorityChange. If you set it to false, onChange event won't be fired.

From API docs version 1.6 (see _setValueAttr in methods):

_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?)

BTW. If you want to add one option there's no need to replace whole set of options - you can call 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>



回答2:


I found a work around to this issue using:

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

which works also when using .set() consecutively on multiple widgets.

Also passing false as third argument to .set() works if you change only one widget at a time.

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

Notes: I could not find reference in the official documentation for this third argument using .set():

Related question: 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>


来源:https://stackoverflow.com/questions/44115583/possible-bug-event-change-fires-after-widget-setoptions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!