Как обновить пользовательскую привязку по нажатию кнопки?
Одним нажатием кнопки я хочу обновить график d3js на основе значений двух выбранных элементов. Если я правильно понимаю, просто позвонив valueAccessor
должен запустить функцию обновления, которая не происходит в моем коде.
У меня есть следующие пользовательские привязки:
ko.bindingHandlers.plotSvg = {
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
valueAccessor();
console.log("Update d3js plot");
}
};
И мнение:
<div class="panel-body">
<div class="row">
<div class="col-xs-2">
<select class="form-control"
data-bind="options: $root.options,
optionsText: 'name',
value: firstSelectedOption">
</select>
</div>
<div class="col-xs-2">
<select class="form-control"
data-bind="options: $root.options,
optionsText: 'name',
value: secondSelectedOption">
</select>
</div>
<div class="col-xs-2 col-xs-offset-5">
<button class="btn btn-primary" data-bind="click: updatePlot">
Visualise
</button>
</div>
</div>
<div data-bind="plotSvg: updatePlot"></div>
</div>
updatePlot
является функцией в модели представления, и все, что она делает, это печатает значение в данный момент.
редактировать JavaScript: http://pastebin.com/2qKLf6yf вид: http://pastebin.com/TPvmKgxL
2 ответа
<div data-bind="plotSvg: updatePlot"></div>
должен ссылаться на вычисленное, иначе нокаут не будет знать, когда значение чего-либо изменилось, и, следовательно, никогда не будет запускать метод обновления пользовательской привязки.
Я бы порекомендовал что-то вроде:
<div data-bind="plotSvg: selectedValue"></div>
а также
ko.bindingHandlers.plotSvg = {
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
viewModel.redrawPlot();
console.log("Update d3js plot");
}
};
где selectedValue
является вычисляемым, который отслеживает текущее выбранное значение в вашей форме и обновляется при нажатии кнопки.
Поскольку вы используете два значения, вы можете сделать что-то подобное в viewModel, чтобы вызвать наблюдаемое изменение:
this.selectedValue = ko.observable(null);
this.updatePlot = function(){
this.selectedValue(this.firstSelectedOption()+""+this.secondSelectedOption()+"")
}
Делая это таким образом, вы получите уникальную строку каждый раз, когда изменяется один из параметров. Если ни то, ни другое не меняется, то наблюдаемое не изменится, и график не должен перерисовываться. Это грубая сила, но она должна работать с тем, что у вас есть.
Когда вы звоните valueAccessor()
Вы просто получаете значение аксессора, поэтому для вызова функции попробуйте это: valueAccessor()()
,
- valueAccessor - функция JavaScript, которую можно вызвать, чтобы получить свойство текущей модели, участвующее в этой привязке. Вызывайте это без передачи каких-либо параметров (например, вызывайте valueAccessor()), чтобы получить значение свойства текущей модели. Чтобы легко принимать как наблюдаемые, так и простые значения, вызовите ko.unwrap для возвращаемого значения.
Ссылка http://knockoutjs.com/documentation/custom-bindings.html