我正在尝试通过该模块(在Api.get()
函数中)中的嵌套函数(基本上是xhr回调(init()
)来设置模块变量/属性,但是它不起作用,我可以不知道为什么。
//posts
var Posts = (function() {
//array of all posts objects
var data = null;
//initialize the posts module
var init = function(callback) {
if(data === null) {
//load all posts
loadAll(function(response){
// data = JSON.parse(response)
var posts = JSON.parse(response)
//create array
data = posts;
// call callback
console.log(data)
callback()
})
}
}
// return all posts from api as json
var loadAll = function(callback) {
Api.get('/api/posts/get', function(response) {
callback(response)
})
}
//public interface
return {
data: data,
init: init,
loadAll: loadAll
}
})();
调用Posts.init()
后,我将Posts.data
登录到控制台,但它仍然是null
。但是,console.log(data)
方法内的init()
记录了试图分配给Posts.data
的对象的预期数组。回调中的data
似乎是Posts.data
之外的另一个变量。有人可以解释为什么,并且在可能的情况下提供一种在data
内设置模块Api.get()
属性的解决方案吗?
答案 0 :(得分:1)
您需要引用返回对象,以便您在返回对象后更改其data
属性。一种方法是使用方法和数据创建一个对象并返回该对象。然后,您可以使用data
在内部引用其this.data
属性:
// Fake API
let Api = {
get(url, cb) {
cb('["testdata"]')
}
}
//posts
var Posts = (function() {
//array of all posts objects
return {
data: null,
init(callback) {
if (this.data === null) {
//load all posts
this.loadAll((response) => { // arrow function needed here for correct `this` binding
var posts = JSON.parse(response)
//create array
this.data = posts; // add data
callback()
})
}
},
loadAll(callback) {
Api.get('/api/posts/get', function(response) {
callback(response)
})
}
}
})();
console.log("initial posts data: ", Posts.data)
Posts.init(() => console.log("After init():", Posts.data))
如果以这种方式进行操作,则除非计划制作多个对象,否则实际上不需要IEFE。您可以只使用Posts = {/* rest of the data and methods */}
。这也可以作为类而不是普通对象使用。