这是我的情况 我正在尝试创建一个仅包含捕获签名的画布的视图。 当我第一次运行代码时,我可以在画布上绘图。 但是当我转到另一个页面并回到签名页面时,画布是可见的,但绘图没有发生。
我扫描了代码,问题似乎发生在
行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
中调用此SignatureViewvar 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();
}
});
如果您认为这种方法可能导致任何问题,请告诉我们?
非常感谢你的时间。欣赏它!
答案 0 :(得分:1)
就像我在评论中提到的那样,你需要确保在每次渲染之前销毁视图。因此,在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;
}
您偶然发现的方法是我在Backbone Views中实现的方式。它有点自以为是,所以我不想让你直接朝着那个方向投掷。很高兴你找到了自己的方式。对于添加的点,您可以创建一个默认包含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.
});