【问题标题】:Backbone with slider带滑块的主干
【发布时间】:2014-01-16 07:30:00
【问题描述】:

这种情况可能适用于一大堆 UI 小部件,但对于一个简单的示例,我将使用滑块(例如 jQuery UI 滑块)。

我有一个 jQuery 滑块,它会在 Backbone.Model “滑动”和停止时通知它。在这两种情况下,视图都会更新。 我想添加 Undo/Redo 功能来监听模型中的更改,并使用 previous() 值为每个更改创建 Undo 对象。但是,我只想在滑块停止时创建 Undo 对象,而不是在滑动期间的每次更改时创建。

因此,我需要滑块以两种不同的方式通知模型滑块值的更改,这两种方式可以通过撤消代码进行区分。

目前,我在滑动时执行 Model.trigger('slideValue', [newValue]) 并且视图在此触发器上侦听和更新。 然后当滑块停止时,我执行 Model.set('slideValue', newValue) 并且 Undo 功能会监听这些更改事件以创建一个新的 Undo 对象并添加到队列中。

我这样做的原因是 Model.trigger('slideValue', [newValue]) 是这样我可以通知所有视图模型正在发生变化(这样他们就可以呈现这种变化),但是当我来到当滑块停止时执行 Model.set('slideValue', newValue),模型的 previous() 值可用于我的 Undo 功能(在滑动过程中未更改)。

但这仍然让人觉得被黑客入侵了。有没有比 Model.trigger() 更好的替代方法?

【问题讨论】:

  • 我不同意使用事件是“骇人听闻的黑客行为”。我所有的应用程序都是专门使用基于事件的架构构建的。它允许每个视图完全独立,因为任何视图都不会直接操作另一个视图。

标签: backbone.js


【解决方案1】:

请考虑这个工作示例http://jsfiddle.net/B4Ar6/1/

我使用Backbone.Collectionstop 事件上添加新的撤消值,并使用Backbone.Modelslide 事件上保持/更新当前滑块值。

// 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 });
});

【讨论】:

  • 感谢您的意见,但这并不是我想要的。我不希望滑块和撤消代码之间有任何联系(它们都应该只知道模型)。我选择在“slide”上调用sliderValueStateModel.trigger("slider", [ui.value]),在“slidestop”上调用sliderValueStateModel.set({value: ui.value})。任何需要显示滑动的组件都可以监听触发,而其他只响应“停止”的组件(例如撤消)只监听更改事件。干杯。
  • 很好,为了获得更好的架构和支持,您还可以考虑使用event busmediator 模式。你可以在这里找到例子jsfiddle.net/B4Ar6/2
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多