Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/88.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 主干上的画布js视图仅渲染/重新加载一次_Javascript_Jquery_Html_Backbone.js_Canvas - Fatal编程技术网

Javascript 主干上的画布js视图仅渲染/重新加载一次

Javascript 主干上的画布js视图仅渲染/重新加载一次,javascript,jquery,html,backbone.js,canvas,Javascript,Jquery,Html,Backbone.js,Canvas,这是我的情况 我试图创建一个视图,其中只包含一个画布来捕获签名。 当我第一次运行代码时,我能够在画布上绘制。 但是,当我转到另一页并返回签名页时,画布是可见的,但绘图没有发生 我扫描了代码,问题似乎发生在线路上 rect=canvas.getBoundingClientRect() 我的rect.left、rect.top、rect.bottom、rect.right都返回0,而只有在第一次运行时才显示15、84、415、384 我已经将画布的宽度和高度设置为400和300 我已附上我的密码 v

这是我的情况 我试图创建一个视图,其中只包含一个画布来捕获签名。 当我第一次运行代码时,我能够在画布上绘制。 但是,当我转到另一页并返回签名页时,画布是可见的,但绘图没有发生

我扫描了代码,问题似乎发生在线路上

rect=canvas.getBoundingClientRect()

我的rect.left、rect.top、rect.bottom、rect.right都返回0,而只有在第一次运行时才显示15、84、415、384

我已经将画布的宽度和高度设置为400和300

我已附上我的密码

var canvas;
var context;
var radius = 2;
var dragging = false;
var targetTouch;
var rect;

var SignatureView = Backbone.View.extend({

  events: {
    "touchstart #SignCanvas": "engage",
    "touchmove #SignCanvas": "putPoint",
    "touchend #SignCanvas": "disengage"
  },

  //Compile and assign the template
  template: getTemplate("signature"),

  initialize: function () {
    this.render();
  },

  //Render the contents
  render: function() {
    this.$el.html(this.template());
    this.delegateEvents();
    var that = this;
    setTimeout(function() {
      that.prepSignPad()
    }, 0);
    return this;
  },

  prepSignPad: function() {
    canvas = document.getElementById("SignCanvas");
    context = canvas.getContext("2d");
    context.lineWidth = radius * 2;
  },

  updateStatus: function() {
    this.$("#divStatusbar").html("Canvas Loaded");
  },

  putPoint: function(e) {
    e.preventDefault();
    targetTouch = e.originalEvent.targetTouches[0];

    rect = canvas.getBoundingClientRect();

    var x = targetTouch.pageX - rect.left;
    var y = targetTouch.pageY - rect.top;

    if(dragging) {
      context.lineTo(x, y);
      context.stroke();
      context.fillStyle = "black";
      context.beginPath();

      context.arc(x, y, radius, 0, Math.PI * 2);
      context.fill();
      context.beginPath();
      context.moveTo(x, y);
    }
  },

  engage: function(e) {
    dragging = true;
    putPoint(e);
  },

  disengage: function() {
    dragging = false;
    context.beginPath();
  }

});
在下面提到的DOrderView中调用此SignatureView

var DOrderView = Backbone.View.extend({

  //Compile and assign the template
  template: getTemplate("DOrder"),
  initialize: function () {
    this.$el.attr('data-role', 'page');
    this.render();
    this.updateStatus();
  },

  //Render the contents
  render: function() {
    this.$el.html(this.template());
  //if(!this.view) {
    this.view = new SignatureView();
  //}

    this.$("#divSignature").append(this.view.el);
    this.view.delegateEvents();
    return this;
  },

  updateStatus: function() {
    this.$("#divStatusbar").html("Delivered Order (DO)");
  }

});
多谢各位。我试着按照你建议的方式编辑代码。我相信它应该会起作用,但由于某种原因它不起作用。这是我听了你的建议后第一次尝试的

var DOrderView = Backbone.View.extend({

//Compile and assign the template
    template: getTemplate("DOrder"),

    initialize: function () {
  this.$el.attr('data-role', 'page');
  this.render();
  this.updateStatus();
},

    //Render the contents
    render: function() {
  this.$el.html(this.template());

  if(this.SignatureView) {
    this.SignatureView.remove();
  }

  this.SignatureView = new SignatureView();

  this.$("#divSignature").append(this.SignatureView.el);
  this.SignatureView.delegateEvents();
    },

updateStatus: function() {
  this.$("#divStatusbar").html("Delivered Order (DO)");
}
这可能是因为父视图DOrderView可能没有被销毁吗

但后来我对代码进行了如下调整,现在它可以工作了

var DOrderView = Backbone.View.extend({

events: {
          "click .back, #btnHome": "close"
},

//Compile and assign the template
    template: getTemplate("DOrder"),

    initialize: function () {
  this.$el.attr('data-role', 'page');
  this.render();
  this.updateStatus();
},

    //Render the contents
    render: function() {
  this.$el.html(this.template());
  this.SignatureView = new SignatureView();

  this.$("#divSignature").append(this.SignatureView.el);
    },

updateStatus: function() {
  this.$("#divStatusbar").html("Delivered Order (DO)");
},

close: function() {
  this.SignatureView.unbind();
  this.SignatureView.remove();
}

});
请让我知道,如果你认为这种方法可能会导致任何问题的线


非常感谢您抽出时间。谢谢你

正如我在评论中提到的,您需要确保在每次渲染之前销毁视图。因此,在您的
DOrderView
的渲染方法中,我们应该首先销毁旧视图,然后再创建新视图。你差一点就到了,只是漏掉了一行:

//Render the contents
render: function() {
  this.$el.html(this.template());

  // The following code block will check if there is already a SignatureView
  // and if there is one, will call the View's `remove()` method. The `remove()`
  // method call's BackboneView's native `stopListening()` method as well as 
  // jQuery's `remove()` method on the view element. 
  if(this.view) {
    this.view.remove(); 
  }

  // Now we will create a fresh view on every render
  this.view = new SignatureView();
  this.$("#divSignature").append(this.view.el);
  this.view.delegateEvents();
  return this;
}
更新: 您偶然发现的方法正是我在主干视图中实现的方法。这有点固执己见,所以我不想马上就把你推向那个方向。很高兴你找到了去那里的路。对于添加的点,可以创建默认情况下包含close方法的基础视图,这样就不必将该方法添加到每个新视图中:

var myBaseView = Backbone.View.extend({

  close: function () {
    this.unbind();
    this.remove();
  }

});
然后你可以像这样使用它:

var myNewExtendedView = myBaseView.extend({

  // Define custom view logic that extends off of base here. This view will come
  // preloaded with the close method. Sweeeeeet.

});

上面的代码看起来不错。当你“离开页面并返回”时,你是否正在破坏视图并创建另一个视图?我相信相关代码在视图实现中,而不是视图本身。jsibales,感谢您回答我的问题。你能告诉我如何破坏和重新创建视图吗?我是否应该在视图中这样做(我第一次在视图中实例化它)?我很乐意向您展示一些示例代码。您当前是如何创建视图的?我将代码粘贴为应答选项卡,因为我不知道如何将代码粘贴到注释中。希望您能在下面看到。您应该在原始问题中添加代码作为编辑。在您的问题标签列表下有一个指向“编辑”的链接。把你的代码贴在那里。太棒了!这是一个极好的建议。现在(这是我第一次)让我看看我应该如何接受并投票支持这个答案。再次感谢!不允许我投票,因为我的声誉还没有达到15分:-(。但是你的答案肯定被接受,并且证明了我所面临的情况是正确的,不用担心…再问几个问题,也许你会回答一两个问题,你就可以开始与社区其他人一起投票了