2013-07-25 4 views
2

Этот сценарий может применяться к целому ряду виджетов пользовательского интерфейса, но для простого примера я использую слайдер (например, слайдер jQuery UI).Магистраль с слайдером

У меня есть ползунок jQuery, который уведомляет Backbone.Model, когда он «скользит», а также когда он останавливается. Обновление обозревателя в обоих случаях. Я хочу добавить функциональность Undo/Redo, которая будет прослушивать изменения в Модели и создавать объекты Undo для каждого изменения, используя предыдущие() значения. Тем не менее, я хочу создавать объекты Undo, когда ползунок STOP, а не при каждом изменении во время скольжения.

Итак, мне нужен ползунок, чтобы уведомить модель изменений значения ползунка двумя разными способами, которые можно отличить с помощью кода отмены.

В настоящий момент я выполняю Model.trigger ('slideValue', [newValue]), когда вы сдвигаетесь, а Views воспроизводит и обновляет этот триггер. Затем, когда слайдер останавливается, я делаю Model.set ('slideValue', newValue), а функция Undo прослушивает эти события изменений для создания нового объекта Undo и добавления в очередь.

Причина, по которой я делаю Model.trigger ('slideValue', [newValue]), заключается в том, что это позволяет мне уведомлять обо всех Представлениях, которые Модель меняет (чтобы они могли визуализировать это изменение), но когда я прихожу для выполнения Model.set ('slideValue', newValue), когда слайдер останавливается, предыдущее() значение Модели доступно для моей функции Отменить (не было изменено во время разворота).

Но это все еще кажется ужасно взломанным. Есть ли более приятная альтернатива Model.trigger()?

+1

Я не согласен с тем, что использование событий «ужасно взломан». Все мои приложения построены исключительно с основанной на событиями архитектурой. Это позволяет каждому виду быть полностью автономным, поскольку никакое представление никогда не будет непосредственно манипулировать другим видом. –

ответ

1

Пожалуйста, обратите внимание этому рабочему примеру http://jsfiddle.net/B4Ar6/1/

Я использовал Backbone.Collection добавить новые значения отката на stop событии и Backbone.Model удерживать/обновить текущее значение слайдера на slide событии.

// Get reference to the slider div 
var sliderDiv = $("#slider"); 

// Get reference to the undo button 
var undoButton = $("#undo"); 

// Create new model to save slider value state 
var sliderValueStateModel = new (Backbone.Model.extend()); 

// Create new collection to save slider undo values 
var sliderValueUndoCollection = new (Backbone.Collection.extend()); 

// Initialize silider 
sliderDiv.slider(); 

// Add initial slider undo value to the collection 
sliderValueUndoCollection.add({ value: sliderDiv.slider("value") }); 

// Listen to the undo button click 
undoButton.on("click", function() { 
    var model, value; 

    // Do nothing when there is no undo history 
    if (sliderValueUndoCollection.length < 2) return false; 

    // Remove the last slider undo model with current value 
    sliderValueUndoCollection.pop(); 

    // Get previous slider undo model 
    if (sliderValueUndoCollection.length === 1) { 
     // Keep initial value in collection 
     model = sliderValueUndoCollection.first(); 
    } else { 
     // Get and remove the value from collection 
     model = sliderValueUndoCollection.pop(); 
    } 

    // Get slider undo value from the model 
    value = model.get("value"); 

    // Save new undo value to the collection 
    sliderValueUndoCollection.add({ value: value }); 

    // Set the new value as previous slider undo value 
    sliderDiv.slider("option", "value", value); 
}); 

// Listen to slide event from slider and set value to the model 
sliderDiv.on("slide", function(event, ui) { 
    // Save new slider value to the model 
    sliderValueStateModel.set({ value: ui.value }); 
}); 

// Listen to stop event from slider and add undo value to the collection 
sliderDiv.on("slidestop", function(event, ui) { 
    // Add new slider undo value to the collection 
    sliderValueUndoCollection.add({ value: ui.value }); 
}); 
+0

Спасибо за ваш вклад, но это не совсем то, что я ищу. Я не хочу никакой связи между слайдером и кодом отмены (оба они должны знать только о модели). Я решил вызвать sliderValueStateModel.trigger («слайдер», [ui.value]) на «слайде» и sliderValueStateModel.set ({значение: ui.value}) на «slidestop». Любые компоненты, которые должны показывать сдвиг, могут прослушивать триггер, в то время как другие, которые реагируют только на «остановку» (например, «Отменить»), только прослушивают события изменения. Приветствия. –

+0

Отлично, для лучшей архитектуры и поддержки вы также можете использовать шаблон 'event bus' или' mediator'. Здесь вы можете найти пример http://jsfiddle.net/B4Ar6/2/ –

Смежные вопросы