2017-09-13 114 views
1

我定義了一個充當堆棧的類,我可以將元素推送到它並撤銷/重做這些元素。Vanilla JS:如何跟蹤另一個對象的對象屬性?

export default class Stack { 
    constructor() { 
    this.history = []; 
    this.pointer = -1; 
    } 

    push(element) { 
    this.pointer += 1; 
    if (this.pointer < this.history.length) { this.history.length = this.pointer; } 
    this.history.push(element); 
    } 

    undo() { 
    if (this.pointer >= 0) { 
     // undo element... 
     this.pointer -= 1; 
    } 
    } 

    redo() { 
    if (this.pointer < this.history.length - 1) { 
     this.pointer += 1; 
     // redo element... 
    } 
    } 

    isEmpty() { 
    return this.history.length === 0; 
    } 

    canUndo() { 
    return !(this.isEmpty() || this.pointer === -1); 
    } 

    canRedo() { 
    return !(this.isEmpty() || this.pointer === this.history.lenght - 1); 
    } 
... 

然後我具有實例化對象Stack並顯示按鈕使用undoredo方法的另一對象;但我需要禁用它們時不能執行這些操作(我已經實現的方法canUndoStackcanRedo來驗證這一點)

我可以禁用按鈕時,我對它們進行初始化,但我不知道如何每次更改堆棧屬性時,是否可以撥打canUndocanRedo方法,以便我可以禁用/啓用它們。對此最好的方法是什麼?

注意:按鈕在畫布中繪製,它們不是普通的HTML元素。我爲此使用ES6和無框架

回答

0

看來你可以使canUndocanRedo成爲堆棧狀態的一個標誌。然後根據stack.canUndostack.canRedo的狀態有條件地將您的按鈕設置爲禁用。

constructor() { 
    this.history = []; 
    this.pointer = -1; 
    this.canUndo = false; 
    this.canRedo = false; 
    } 

只要添加一點邏輯的在你的canUndocanRedo方法,用來切換標誌,如果你從canUndo狀態去一個cantUndo狀態。

canUndo() { 
    const isPossible = !(this.isEmpty() || this.pointer === -1); 
    this.canUndo = isPossible; 
    return isPossible; 
} 

如果你這樣做了,那麼使用堆棧的外部事物就可以讀取堆棧的屬性。

0

您可以創建一個監聽器模式:

class Listener { 
    constructor(){ 
    this.listeners = new Map(); 
    } 
    on(name, func){ 
    if(! this.listeners.has(name)){ 
     this.listeners.set(name,[func]); 
    }else{ 
     this.listeners.get(name).push(func); 
    } 
    } 
    trigger(name,...values){ 
    const l = this.listeners.get(name); 
    if(!l) return; 
    l.forEach(func => func(...values)); 
    } 
} 

所以可以這樣做:

class Stack extends Listener { 
    constructor(){ 
    super(); 
    } 
    //in every method that enables the undo state 
    this.trigger("undo",true); 
    //in every method that enables the undo state 
    this.trigger("undo",false); 
    //in every method that enables the redo state 
    this.trigger("redo",true); 
    //in every method that disables the redo state 
    this.trigger("redo",false); 
} 

然後,如果你想動態按鈕例如,一個可以做:

const events = new Stack(); 

events.on("redo", state => { 
    const button = document.getElementById("redo"); 
    button.disabled = ! state; 
}); 
相關問題