gpt4 book ai didi

javascript - 从ajax请求动态连接Vue中的数组不起作用

转载 作者:行者123 更新时间:2023-12-02 22:44:32 25 4
gpt4 key购买 nike

我有一个相当简单的 Vue 实例,它从 REST 端点检索对象并将它们显示在页面上。几乎一切都正常工作(例如过滤),除非我通过向服务请求新的结果“页面”来将新对象添加到结果集中。此操作与其他操作的区别在于,我尝试将服务中的新结果添加到现有结果集中。由于该服务仅返回所请求的结果“页面”,因此我无法完全替换该数组,而是必须将其添加到 Vue 实例中的现有结果集中。这是有问题的代码:

// these come from an external server-side process rendered in a separate place so are defined outside of the Vue context
let searchTags = ["tag1", "tag2", "etc"];
let productsBaseSearchTag = "a/b/c";

Vue.mixin({
methods: {
doSearchStuff: function(response, data) {
this.searchResponse = response;
this.resultCount = response.total; // this doesn't seem to be working consistently either so I'm doing it with jQuery
jQuery(".search-page-sort-results .num").text(this.resultCount);
if(this.currentPage > 1) {
this.searchResults = this.searchResults.concat(data.hits);
} else {
this.searchResults = data.hits;
}
this.facetCount = data.facets.length;
}
}
});

new Vue({
el: '#v-search-page-results',
data: {
searchResponse: {},
searchResults: [],
facetHeaders: searchTags,
returnedFacetHeaders: undefined,
currentPage: 1,
hitsPerPage: 12,
searchTerm: "",
statusMessage: "",
sortProperty: "",
displayedFilters: {},
predicateList: [],
facetCount: 0,
resultCount: 0,
showLoading: true
},
created: function() {
this.predicateList = searchTags;
this.getSearchResults(false);
},
computed: {
pdpPaths: function() {
return this.searchResults.map(function(item) {
let catalogPath = item.path;
return decodeURIComponent(pdpPath) + catalogPath.replace(decodeURIComponent(catalogRoot), "").replace(/\//g, ".");
});
},
summaries: function() {
return this.searchResults.map(function(item) {
let summary = item.properties.summary;
if (summary.length >= 120) {
summary = summary.substring(0, 120);
summary = summary.substring(0, summary.lastIndexOf(" ")) + "...";
}
return summary;
});
},
assetAbsoluteURLs: function() {
return this.searchResults.map(function(item) {
let escapedUrl = item.path.replace(/\s/g, "%20");
return location.origin + escapedUrl;
});
},
canClearFilters: function() {
return this.predicateList !== searchTags;
},
moreResults: function() {
if(this.searchResponse) {
let resultCount = this.resultCount;
let totalLoadedResults = this.hitsPerPage * this.currentPage;
if(totalLoadedResults < resultCount) {
return true;
}
}
return false;
}
},
methods: {
loadMoreResults: function() {
this.currentPage += 1;
this.getSearchResults();
},
clearSearchTerm: function() {
this.searchTerm = "";
this.submitSearchTerm();
},
getSearchFilters: function() {
if(this.predicateList.length > 0) {
return this.predicateList;
} else {
this.predicateList = searchTags;
return this.predicateList;
}
},
getSearchResults: function(xhrAsync=true) {
let query = this.buildQuery();

var jqXhr = $.ajax({
url: query,
async: xhrAsync, // search breaks if we don't set this to false on the initial page load search
context: this
});

if(!this.returnedFacetHeaders) {
jqXhr.done(function(response) {
let data = response;
this.doSearchStuff(response, data);

this.returnedFacetHeaders = data.facetHeaders;

if(queryParams.q) {
this.searchTerm = decodeURIComponent(queryParams.q);
}
if(queryParams.tags) {
this.predicateList = queryParams.tags;
}
}).done(function () {
this.getSearchResults();
});
} else {
jqXhr.done(function(response) {
let data = response;
this.doSearchStuff(response, data);
});
}
},
submitSearchTerm: function() {
this.resetSearch();
},
resetSearch: function() {
this.currentPage = 1;
this.getSearchResults();
},
buildQuery: function() {
let offset = (this.currentPage - 1) * this.hitsPerPage;

query = "..."; // not relevant

return query;
}
}
});

代码中发生的事情比这多得多,但这是与数组相关的部分。它不会在此 block 之外更新。这是使用 v-for 迭代数组的相应标记:

<div id="v-search-page-results" class="search-page-container _clearfix">
<div class="search-page-wrapper">
<div class="search-page-facets-wrapper">
<div class="search-page-sort-results">
<span v-cloak class="num">{{ resultCount }}</span> results
</div>

</div>

<div class="search-page-container">

<!-- facet stuff here -->

<div class="search-page-results-container">
<div class="search-page-results-wrapper">

<div v-for="(result, index) in searchResults" class="search-page-results-item" v-bind:key="result.id">
<div class="search-page-image-container">
<img v-cloak :alt="result.title" :src="result.properties.thumbnailPath" class="search-page-image">
</div>
<div class="search-page-results-content">
<a v-cloak :href="pdpPaths[index] + '.html'" class="title" title="">{{ result.properties.productTitle }}</a>
<div v-cloak class="description" v-html="summaries[index]"></div>
</div>
</div>

</div>

<div class="search-button-top-nav">
<div v-show="moreResults" class="button-wrapper load-more-container load-more-wrapper">
<div class="button-wrapper-2">
<div class="button-container">
<a @click="loadMoreResults" class="btn -primary load-more">Load More</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>

最后,这是我们尝试迭代的数据示例:

"hits": [
{
"id": 1,
"title": "product1",
"path": "/path/to/product1",
"properties": {
"thumbnailPath": "/products/images/product1.jpg",
"productTitle": "Product 1",
"summary": "<p>This is product 1.</p>\r\n"
}
},
{
"id": 2,
"title": "product2",
"path": "/path/to/product2",
"properties": {
"thumbnailPath": "/products/images/product2.jpg",
"productTitle": "Product 2",
"summary": "<p>This is product 2.</p>\r\n"
}
}
]

我尝试过使用 Vue.set,我尝试过迭代响应对象并一次将一个对象推送到数组,我尝试过使用展开运算符等。在代码中,数组正在被添加成功,但是Vue不会显示新的结果。如果我用新对象覆盖当前数组中的现有对象,它会正确显示,所以并不是说 DOM 根本没有更新,它只是更新为仅显示前 X 个结果,永远不会比那更多的。看起来应该可行,但事实并非如此。

最佳答案

您不应该将 jQuery 与 Vue 混合使用 - 您最终会因直接操作 DOM 而失去 react 性,或者经历一些其他不良影响。

new Vue({
el: '#app',
data: {
searchResults: [],
},
methods: {
async getNewPost(next) {
this.searchResults.push(await this.getSearchResult(next))
},
getSearchResult(next) {
return fetch(`https://jsonplaceholder.typicode.com/posts/${next}`)
.then(response => response.json())
.then(json => {
return json
})
}
},
async mounted() {
this.searchResults = [await this.getSearchResult(this.searchResults.length + 1)]

}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<button @click="getNewPost(searchResults.length + 1)">Get new post</button>
<div v-for="(result, index) in searchResults" class="search-page-results-item" v-bind:key="result.id">
<div class="search-page-results-content">
<h3>{{index + 1}}. {{result.title}}</h3>
<div v-cloak class="description">{{result.body}}</div>
</div>
</div>
</div>

上面的代码片段从模型 JSON API 获取数据,按下按钮即可获取下一项。

您可以看到,在 getNewPost() 方法中,我没有直接推送项目到 searchResults 数据属性中,而是创建一个临时项目变量,然后更改整个数组

关于javascript - 从ajax请求动态连接Vue中的数组不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58459468/

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