Я написал собственный обработчик привязки, чтобы привязать данные вида viewmodel к диаграмме высоких диаграмм. У этого действительно есть 2 части, одна связывает исходную конфигурацию, необходимую для высоких диаграмм, вторая привязывает серию к диаграмме.Пользовательский перехват нокаута срабатывает дважды, неожиданно
вот bindingHandler
код
ko.bindingHandlers.highchart = {
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var value = valueAccessor();
var valueUnwrapped = ko.unwrap(value);
console.log ('update',element.id,valueUnwrapped);
if(allBindings.get('series')){
var series = allBindings.get('series');
var seriesUnwrapped = ko.unwrap(series);
if(!$.isArray(seriesUnwrapped)){
seriesUnwrapped = [seriesUnwrapped];
}
console.log('seriesUnwrapped',element.id,seriesUnwrapped)
valueUnwrapped.series = seriesUnwrapped;
}
$(element).highcharts(valueUnwrapped);
}
}
Теперь у меня есть 2 набора тестов для этого, первые работы, как и ожидалось. Он связывает диаграмму с несколькими рядами, и когда я добавляю к наблюдаемому массиву, связанному с series
, он обновляет график только один раз. Посмотрите на this fiddle и посмотрите консоль, когда вы нажимаете кнопку «Добавить». Выход вы получаете
обновление контейнера объекта {диаграмма = {...}}
seriesUnwrapped контейнер [Объект {Name = "Scenario0", цвет = "красный", данные = [9]} , Object {name = "Scenario1", color = "green", data = [9]}]
Указывая, что мы прошли вышеуказанный код только один раз.
Теперь проверьте мою вторую скрипку: http://jsfiddle.net/8j6e5/9/. Это немного отличается, поскольку начальная конфигурация старших карт - это computed
, наблюдаемая, как и серия. Когда вы нажмете кнопку «Добавить» на этом, вы увидите, что привязка выполняется дважды:
update container2 Object {chart = {...}, xAxis = {...}, series = [ 1]}
seriesUnwrapped container2 [Object {name = "Scenario2", color = "blue", data = [2]}]
update container2 Object {chart = {...}, xAxis = {...} }
seriesUnwrapped container2 [Объект {имя = "Scenario2", цвет = "синий", данные = [2]}]
Я предполагаю, что использование allBindings.get('series')
в пределах моих Highcharts привязки обработчика я установил зависеть от него, и когда обе привязки меняют свое выполнение двойных привязок в два раза. Мой вопрос в том, есть ли способ остановить это или написать эту функцию любым другим способом, чтобы этого не произошло?
Вы должны решить, когда вы хотите, чтобы ваша функция обновления будет называться. Поэтому, когда изменяется связанное свойство или изменяется связанное свойство 'series'. И затем используйте 'peek()' вместо 'ko.unwrap':' var seriesUnwrapped = series.peek(); 'или' var valueUnwrapped = value.peek(); 'вам, конечно, потребуется проверка для проверки' value' или 'series' являются действительно наблюдаемыми, прежде чем вызывать peek на них. – nemesv
@nemesv - Это очень хорошее начало, это само по себе устраняет проблему двойного вызова. Однако после выполнения этого простого изменения моя первая скрипка больше не будет обновляться (поскольку она привязана к вычисленной серии, но статическое свойство highchart). У вас 2/3 пути к очень хорошему ответу. – Jamiec
Если вы делаете это со значением 'var valueUnwrapped = ko.isObservable (value)? value.peek(): value; 'исправляет оба. Но в случае, когда ваша привязка - это «highchart: yourProp, series: otherProp» и только «yourProp» изменяется, а «otherProp» - нет, значит, он не обновит вашу диаграмму правильно ... – nemesv