问题
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 option
s 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