admin管理员组文章数量:1289603
Trying out VueJS 2.0 RC, and using the fetch API to load some data for some of the ponents. Here's a mock example:
const Component = {
template: '#p',
name: "some-ponent",
data: function () {
return {
basic: data.subset,
records: function () {
return fetch('/datasource/api', {
method: 'get'
}).then(function (response) {
return response.json();
}).then(function (response) {
if (response.status == "success") {
return response.payload;
} else {
console.error(response.message);
}
}).catch(function (err) {
console.error(err);
});
}
}
}
};
The data
object is a global application state, defined before the app's initialization, and only a subset of it is needed in the ponent, hence that part. The main set of the ponent's data es from another endpoint which I'm trying to call. However, the data
property expects an object, and it's getting back a Promise it can't really use in the context of a loop in the template for rendering etc (e.g. v-for="record in records"
)
Am I going about this the wrong way? What's the approach to get the data records
property to update once it's fully fetched? Is there a way to force the code to stop until the promise resolves (effectively making it sync)? The ponent is useless without the data anyway, so there's a waiting period before it can be used regardless.
What is the right way to asynchronously populate a ponent's data field without using plugins like vue-async or vue-resource?
(I know I could use the XHR/jQuery methods of non-promise ajax calls to do this, but I want to learn how to do it using fetch)
Update: I tried defining a created hook, and a method to load the data, like this but no dice - in my own experiments, the records property fails to update once it's loaded. It doesn't change, even though the data is successfully fetched (successfully logs into console).
Could have something to do with me using vue-router and the ponent I'm dealing with triggering when a link is clicked, as opposed to being a regular Vue ponent. Investigating further...
Update #2: If I continue investigating the jsfiddle approach above and log this.records
and response.payload
to the console, it shows the records object being populated. However, this doesn't seem to trigger a change in the template or the ponent itself - inspecting with Vue dev tools, the records property remains an empty array. Indeed, if I add a method logstuff
and a button into the template which calls it, and then have this method log this.records
into the console, it logs an observer with an empty array:
Now I'm wondering why the data property of a ponent would be not updated even after it's explicitly set to another value. Tried setting up a watcher for $route
that triggers the reload
method, but no dice - every subsequent load of that route does indeed re-issue the fetch, and the console logs this.records
as populated (from within fetch), but the "real" this.records
remains an empty array.
Trying out VueJS 2.0 RC, and using the fetch API to load some data for some of the ponents. Here's a mock example:
const Component = {
template: '#p',
name: "some-ponent",
data: function () {
return {
basic: data.subset,
records: function () {
return fetch('/datasource/api', {
method: 'get'
}).then(function (response) {
return response.json();
}).then(function (response) {
if (response.status == "success") {
return response.payload;
} else {
console.error(response.message);
}
}).catch(function (err) {
console.error(err);
});
}
}
}
};
The data
object is a global application state, defined before the app's initialization, and only a subset of it is needed in the ponent, hence that part. The main set of the ponent's data es from another endpoint which I'm trying to call. However, the data
property expects an object, and it's getting back a Promise it can't really use in the context of a loop in the template for rendering etc (e.g. v-for="record in records"
)
Am I going about this the wrong way? What's the approach to get the data records
property to update once it's fully fetched? Is there a way to force the code to stop until the promise resolves (effectively making it sync)? The ponent is useless without the data anyway, so there's a waiting period before it can be used regardless.
What is the right way to asynchronously populate a ponent's data field without using plugins like vue-async or vue-resource?
(I know I could use the XHR/jQuery methods of non-promise ajax calls to do this, but I want to learn how to do it using fetch)
Update: I tried defining a created hook, and a method to load the data, like this but no dice - in my own experiments, the records property fails to update once it's loaded. It doesn't change, even though the data is successfully fetched (successfully logs into console).
Could have something to do with me using vue-router and the ponent I'm dealing with triggering when a link is clicked, as opposed to being a regular Vue ponent. Investigating further...
Update #2: If I continue investigating the jsfiddle approach above and log this.records
and response.payload
to the console, it shows the records object being populated. However, this doesn't seem to trigger a change in the template or the ponent itself - inspecting with Vue dev tools, the records property remains an empty array. Indeed, if I add a method logstuff
and a button into the template which calls it, and then have this method log this.records
into the console, it logs an observer with an empty array:
Now I'm wondering why the data property of a ponent would be not updated even after it's explicitly set to another value. Tried setting up a watcher for $route
that triggers the reload
method, but no dice - every subsequent load of that route does indeed re-issue the fetch, and the console logs this.records
as populated (from within fetch), but the "real" this.records
remains an empty array.
1 Answer
Reset to default 5The solution was the jsfiddle approach, with a twist. This part:
reload: function () {
fetch('/data/api', {
method: 'get'
}).then(function (response) {
return response.json();
}).then(function (response) {
if (response.status == "success") {
this.records = response.payload;
} else {
console.error(response.message);
}
}).catch(function (err) {
console.error(err);
});
}
needed a .bind(this)
in the part which sets the this.records
value after the fetch, like so:
reload: function () {
fetch('/data/api', {
method: 'get'
}).then(function (response) {
return response.json();
}).then(function (response) {
if (response.status == "success") {
this.records = response.payload;
} else {
console.error(response.message);
}
}.bind(this)).catch(function (err) {
console.error(err);
});
}
This post was what made it click for me.
Lesson learned: in modern JS, always keep scope in mind.
本文标签: javascriptVueJS async component data and promisesStack Overflow
版权声明:本文标题:javascript - VueJS async component data and promises - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741405819a2376937.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论