Trigger Knockout-Event from outside

两盒软妹~` 提交于 2021-02-11 07:16:25

问题


I have the following Select-Element in an html-form:

<select multiple="multiple" data-bind="options: candidateList, optionsValue: 'id', optionsText: 'title', optionsAfterRender: setOptionTitle, selectedOptions: selectedCandidates, optionsAfterRender: setOptionTitle, event: { dblclick: addSelectedCandidate, change: candidateChanged }, enable: enabled()">
<option title="first" value="1">first</option>
<option title="second" value="2">second</option>
<option title="third" value="3">third</option>
</select>

Now I select multiple Elements of that Select using jQuery-Methods setting the "Option SELECTED" - value.

As you can see, that select has a data-binding on it, which is from knockout. That knockout-code is in another JavaScript-File provided by someone else. We cannot really change content there. And our code is NOT knockout-, but simple jQuery-Code.

Now my problem is, that there are validations on that select. When I click onto an element manually, this enables another Button etc.

But when I try to do this by code, nothing happens. I tried inserting the "selected", $(option).trigger('click'), $(option).click(), $(option).trigger('change') and $(option).change();

Is there any way to force knockout to "recognize" the stuff we change programmatically?


回答1:


Use val and then trigger('change') and it'll work. Here's a demo:

ko.applyBindings({
  candidateList: [{ id: 1, title: "first" }, { id: 2, title: "second" }, { id: 3, title: "third" }],
  setOptionTitle: function() { },
  selectedCandidates: ko.observableArray(),
  addSelectedCandidate: function() { },
  candidateChanged: function() { },
  enabled: ko.observable(true)
});

function getRandomVal() { return (Math.floor(Math.random() * (3 - 1)) + 1).toString(); }

window.setInterval(function() {
  var vals = [];
  if (Math.random() > 0.75) { vals.push(getRandomVal()); }
  if (Math.random() > 0.75) { vals.push(getRandomVal()); }
  if (Math.random() > 0.75) { vals.push(getRandomVal()); }
  $("select").val(vals).trigger("change");
}, 1000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>

<select multiple="multiple" data-bind="options: candidateList, optionsValue: 'id', optionsText: 'title', optionsAfterRender: setOptionTitle, selectedOptions: selectedCandidates, optionsAfterRender: setOptionTitle, event: { dblclick: addSelectedCandidate, change: candidateChanged }, enable: enabled()">
<option title="first" value="1">first</option>
<option title="second" value="2">second</option>
<option title="third" value="3">third</option>
</select>

<hr>
Selected candidates: <code data-bind="text: ko.toJSON($root.selectedCandidates, null, 2)"></code>

PS. You have mostly a political problem probably, if you cannot change the code where your changes probably actually should go. Mixing jQuery and KO like this will hurt you in the short run, and it will hurt you badly in the long run.

PPS. There's a few weird things (without context at least) in that KO code as posted. First, it has options in it, but those should be generated. Second, the change event is listened to, but typically a subscription or writeable computed would be a better choice. Third, the optionsAfterRender is declared twice. Lastly, the enabled value is executed, which is superfluous if it would be an observable.



来源:https://stackoverflow.com/questions/35840257/trigger-knockout-event-from-outside

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