2017-09-13 9 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); 
    } 
... 

そしてIはStackオブジェクトをインスタンス化undoredo方法を使用するボタンが表示され、別のオブジェクトを持っています。しかし、私はそれらを初期化するとき、私はボタンを無効にすることができ

(私はこれを検証するためにStackに方法canUndocanRedoを実装している)これらの操作を実行できないときにそれらを無効にする必要がありますが、私は方法がわかりませんスタックのプロパティが変更されるたびにcanUndocanRedoのメソッドを呼び出すことができます。そのため、これらのメソッドを無効にしたり有効にしたりできます。このための最良の方法は何でしょうか?

注:ボタンはキャンバスに描かれており、通常のHTML要素ではありません。私はES6とフレームワークなしこれを使用しています。

答えて

0

canUndocanRedoはあなたのスタックの状態でフラ​​グを立てるようです。次に、stack.canUndoまたはstack.canRedoの状態に基づいて、条件付きでボタンを無効にレンダリングします。

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

はちょうどあなたがcantUndo状態にcanUndo状態からつもりならフラグをトグルあなたのcanUndocanRedo方法でロジックを少し追加します。

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

だから、1が行うことができます:

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

そして、あなたは例えば、ダイナミックボタンをしたい場合は、1つは行うことができます。

const events = new Stack(); 

events.on("redo", state => { 
    const button = document.getElementById("redo"); 
    button.disabled = ! state; 
}); 
関連する問題