Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Vanilla JS:如何跟踪对象';来自另一个对象的属性?_Javascript - Fatal编程技术网

Javascript Vanilla JS:如何跟踪对象';来自另一个对象的属性?

Javascript Vanilla JS:如何跟踪对象';来自另一个对象的属性?,javascript,Javascript,我定义了一个充当堆栈的类,我可以将元素推送到它并撤消/重做这些元素 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.p

我定义了一个充当堆栈的类,我可以将元素推送到它并撤消/重做这些元素

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);
  }
...
导出默认类堆栈{
构造函数(){
这个。历史=[];
this.pointer=-1;
}
推动(元件){
这个指针+=1;
如果(this.pointer=0){
//撤消元素。。。
这个指针-=1;
}
}
重做{
if(this.pointer
然后我有另一个对象,它实例化了一个
堆栈
对象,并显示使用
undo
redo
方法的按钮;但是当无法执行这些操作时,我需要禁用它们(我已经在
堆栈
中实现了
canUndo
canRedo
方法来验证这一点)

我可以在初始化按钮时禁用它们,但我不知道如何在每次更改堆栈属性时调用
canUndo
canRedo
方法,因此我可以手动禁用/启用它们。最好的方法是什么


注意:按钮是在画布上绘制的,它们不是普通的HTML元素。我正在使用ES6和无框架来实现这一点。

似乎可以在堆栈状态中设置
canUndo
canRedo
标记。然后根据
堆栈的状态有条件地将按钮呈现为禁用状态。canUndo
或者
stack.canRedo

  constructor() {
    this.history = [];
    this.pointer = -1;
    this.canUndo = false;
    this.canRedo = false;
  }
只要在您的
canUndo
canRedo
方法中添加一点逻辑,如果您要从canUndo状态切换到cantUndo状态,就可以切换标志

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

如果您这样做,那么使用堆栈的外部事物就可以读取堆栈的属性。

看起来您可以在堆栈状态中设置
canUndo
canRedo
标记。然后根据
堆栈的状态有条件地将按钮呈现为禁用状态。canUndo
stack.canRedo

  constructor() {
    this.history = [];
    this.pointer = -1;
    this.canUndo = false;
    this.canRedo = false;
  }
只要在您的
canUndo
canRedo
方法中添加一点逻辑,如果您要从canUndo状态切换到cantUndo状态,就可以切换标志

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

如果您这样做,那么使用堆栈的外部事物就可以读取堆栈的属性。

您可以创建一个侦听器模式:

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;
});
然后,如果您想要动态按钮,例如,可以执行以下操作:

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

您可以创建一个侦听器模式:

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;
});
然后,如果您想要动态按钮,例如,可以执行以下操作:

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