gpt4 book ai didi

javascript - 调用函数时出现 Backbone 问题

转载 作者:行者123 更新时间:2023-12-03 12:39:44 24 4
gpt4 key购买 nike

我对 javascript 非常缺乏经验,所以如果这真的很明显,请原谅我......

我使用此处找到的 TodoMVC 示例 ( http://todomvc.com/architecture-examples/backbone/ ) 作为 Cordova 项目的基础。我遇到的问题是将其与相机和地理位置插件结合使用,从相机/地理位置回调函数中调用 js/views/app-view.js 中的任何函数时都会出错。我假设这是一个上下文问题,但我对 javascript 的了解不够,无法解决它。

例如,TodoMVC 项目使用这行代码在 js\views\app-view.js 中添加新项目:

app.todos.create(this.newAttributes());

我试图将其与相机功能结合起来,用手机相机拍照,然后添加一个新的待办事项,并将图片存储在其中。一切正常,除了当我尝试在相机回调函数中使用上面的代码行时,在底部如下所示:

onCameraSuccess: function(imageData) {
// Stores image data in a hidden field to be used later. Not best method but it works
document.getElementById('imageData').value = "data:image/jpeg;base64," + imageData;

// This line should create a new item
app.todos.create(this.newAttributes());
},

它给出了错误“未定义不是函数”,似乎指的是“this.newAttributes()”。这似乎又是一个上下文问题,因为同一行代码几乎可以在同一脚本中的任何其他地方工作。

OnCameraSuccess是Camera的getPicture函数的回调函数:

Camera: function() {
navigator.camera.getPicture(this.onCameraSuccess, this.onCameraFail, { quality: 50,
destinationType: Camera.DestinationType.DATA_URL,
targetWidth: 250,
targetHeight: 250,
correctOrientation: true
});
},

同样,地理定位函数需要两个回调函数,用于成功和错误,但我找不到一种可接受的方法来引用其他函数,而这些函数不会给出 TYPE_MISMATCH_ERR 来表明这些函数不是函数。

onDeviceReady: function() {
//This line calls the geolocation function and specifies the two callback functions, but it thinks they don't exist
navigator.geolocation.watchPosition(this.onLocationSuccess, this.onLocationError, {enableHighAccuracy : true});
},

onLocationSuccess: function(position) {
// map logic
},

onLocationError: function(error) {
alert('code: ' +error.code+ '\n' + 'message: ' +error.message + '\n');
},

它们位于 onDeviceReady 函数的正下方,但由于某种原因找不到它们。 this.onLocationSuccess 不起作用(尽管这就是它引用所有其他函数的方式), self.onLocationSuccess 不起作用...同样,这似乎是上下文问题,但我无法弄清楚.

有什么想法吗?我什至对 javascript 的了解还不够,不知道我是否充分解释了这一点,所以也请随意对我大喊大叫。

最佳答案

JavaScript 中 this 的值取决于函数的调用方式。例如,这个:

var obj = {
f: function() { console.log(this) }
};
obj.f();

会将obj放入控制台,但是:

var obj = {
f: function() { console.log(this) }
};
var f = obj.f;
f();

(通常)会将 window 转储到控制台,即使正在调用相同的函数。当几乎每个人开始使用 JavaScript 时,这种 this 行为都会让他们感到困惑。就您而言,文档没有说明 getPicture 回调中的 this 内容,因此 this 可能会是 window 而不是你的对象。

如果您需要一个带有 JavaScript 回调函数的特定 this,您通常必须自己安排。一种方法是将所需的 this 存储在变量中并使用匿名函数:

var _this = this;
navigator.camera.getPicture(
function(imageData) { _this.onCameraSuccess(imageData) },
...
);

更简洁的方法(尤其是当函数有参数时)是使用 $.proxy 将函数绑定(bind)到所需的 this , _.bind , Function.prototype.bind ,或几乎每个 JavaScript 工具包都附带的类似实用程序。例如,考虑到:

var obj = {
f: function() { console.log(this) }
};
var f1 = $.proxy(obj.f, obj);
var f2 = _(obj.f).bind(obj);
var f3 = obj.f.bind(obj);

调用 f1()f2()f3() 都会将 obj 转储到安慰。 Underscore 是 Backbone 的典型工具包,因此这很常见:

navigator.camera.getPicture(
_(this.onCameraSuccess).bind(this),
_(this.onCameraFail).bind(this),
{ ... }
);

Underscore还提供_.bindAll ,这通常在 initialize 中用于就地绑定(bind)多个函数:

initialize: function() {
_.bindAll(this, 'onCameraSuccess', 'onCameraFail');
//...
}

然后你就可以使用this.onCameraSuccess而不必担心绑定(bind):

navigator.camera.getPicture(
this.onCameraSuccess,
this.onCameraFail,
{ ... }
);

initialize中使用_.bindAll可能是Backbone中最常见的方法。

关于javascript - 调用函数时出现 Backbone 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23576470/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com