我的方法是:
computed: {
filteredClasses() {
let classes = this.project.classes
const ret = classes && classes.map(klass => {
const klassRet = Object.assign({}, klass)
klassRet.methods = klass.methods.filter(meth => this.isFiltered(meth, klass))
return klassRet
})
console.log(JSON.stringify(ret))
return ret
}
}
console.log
语句打印出的值是正确的,但是当我在模板中使用filteredClasses
时,它只使用第一个缓存的值,并且从未更新模板。这已经通过Vue chrome devtools确认(filteredClasses
在初始缓存后从未更改)。
有人能告诉我为什么会发生这种情况吗?
Project.vue
<template>
<div>
<div class="card light-blue white-text">
<div class="card-content row">
<div class="col s4 input-field-white inline">
<input type="text" v-model="filter.name" id="filter-name" />
<label for="filter-name">Name</label>
</div>
<div class="col s2 input-field-white inline">
<input type="text" v-model="filter.status" id="filter-status" />
<label for="filter-status">Status (PASS or FAIL)</label>
</div>
<div class="col s2 input-field-white inline">
<input
type="text"
v-model="filter.apkVersion"
id="filter-apkVersion"
/>
<label for="filter-apkVersion">APK Version</label>
</div>
<div class="col s4 input-field-white inline">
<input
type="text"
v-model="filter.executionStatus"
id="filter-executionStatus"
/>
<label for="filter-executionStatus"
>Execution Status (RUNNING, QUEUED, or IDLE)</label
>
</div>
</div>
</div>
<div v-for="(klass, classIndex) in filteredClasses">
<ClassView :klass-raw="klass" />
</div>
</div>
</template>
<script>
import ClassView from './ClassView.vue'
export default {
name: 'ProjectView',
props: {
projectId: {
type: String,
default () {
return this.$route.params.id
}
}
},
data () {
return {
project: {},
filter: {
name: '',
status: '',
apkVersion: '',
executionStatus: ''
}
}
},
async created () {
// Get initial data
const res = await this.$lokka.query(`{
project(id: "${this.projectId}") {
name
classes {
name
methods {
id
name
reports
executionStatus
}
}
}
}`)
// Augment this data with latestReport and expanded
const reportPromises = []
const reportMeta = []
for (let i = 0; i < res.project.classes.length; ++i) {
const klass = res.project.classes[i]
for (let j = 0; j < klass.methods.length; ++j) {
res.project.classes[i].methods[j].expanded = false
const meth = klass.methods[j]
if (meth.reports && meth.reports.length) {
reportPromises.push(
this.$lokka
.query(
`{
report(id: "${
meth.reports[meth.reports.length - 1]
}") {
id
status
apkVersion
steps {
status platform message time
}
}
}`
)
.then(res => res.report)
)
reportMeta.push({
classIndex: i,
methodIndex: j
})
}
}
}
// Send all report requests in parallel
const reports = await Promise.all(reportPromises)
for (let i = 0; i < reports.length; ++i) {
const { classIndex, methodIndex } = reportMeta[i]
res.project.classes[classIndex].methods[methodIndex].latestReport =
reports[i]
}
this.project = res.project
// Establish WebSocket connection and set up event handlers
this.registerExecutorSocket()
},
computed: {
filteredClasses () {
let classes = this.project.classes
const ret =
classes &&
classes.map(klass => {
const klassRet = Object.assign({}, klass)
klassRet.methods = klass.methods.filter(meth =>
this.isFiltered(meth, klass)
)
return klassRet
})
console.log(JSON.stringify(ret))
return ret
}
},
methods: {
isFiltered (method, klass) {
const nameFilter = this.testFilter(
this.filter.name,
klass.name + '.' + method.name
)
const statusFilter = this.testFilter(
this.filter.status,
method.latestReport && method.latestReport.status
)
const apkVersionFilter = this.testFilter(
this.filter.apkVersion,
method.latestReport && method.latestReport.apkVersion
)
const executionStatusFilter = this.testFilter(
this.filter.executionStatus,
method.executionStatus
)
return (
nameFilter && statusFilter && apkVersionFilter && executionStatusFilter
)
},
testFilter (filter, item) {
item = item || ''
let outerRet =
!filter ||
// Split on '&' operator
filter
.toLowerCase()
.split('&')
.map(x => x.trim())
.map(seg =>
// Split on '|' operator
seg
.split('|')
.map(x => x.trim())
.map(segment => {
let quoted = false,
postOp = x => x
// Check for negation
if (segment.indexOf('!') === 0) {
if (segment.length > 1) {
segment = segment.slice(1, segment.length)
postOp = x => !x
}
}
// Check for quoted
if (segment.indexOf("'") === 0 || segment.indexOf('"') === 0) {
if (segment[segment.length - 1] === segment[0]) {
segment = segment.slice(1, segment.length - 1)
quoted = true
}
}
if (!quoted || segment !== '') {
//console.log(`Item: ${item}, Segment: ${segment}`)
//console.log(`Result: ${item.toLowerCase().includes(segment)}`)
//console.log(`Result': ${postOp(item.toLowerCase().includes(segment))}`)
}
let innerRet =
quoted && segment === ''
? postOp(!item)
: postOp(item.toLowerCase().includes(segment))
//console.log(`InnerRet(${filter}, ${item}): ${innerRet}`)
return innerRet
})
.reduce((x, y) => x || y, false)
)
.reduce((x, y) => x && y, true)
//console.log(`OuterRet(${filter}, ${item}): ${outerRet}`)
return outerRet
},
execute (methID, klassI, methI) {
this.project.classes[klassI].methods[methI].executionStatus = 'QUEUED'
// Make HTTP request to execute method
this.$http.post('/api/Method/' + methID + '/Execute').then(
response => {},
error => console.log("Couldn't execute Test: " + JSON.stringify(error))
)
},
registerExecutorSocket () {
const socket = new WebSocket('ws://localhost:4567/api/Executor/')
socket.onmessage = msg => {
const { methodID, report, executionStatus } = JSON.parse(msg.data)
for (let i = 0; i < this.project.classes.length; ++i) {
const klass = this.project.classes[i]
for (let j = 0; j < klass.methods.length; ++j) {
const meth = klass.methods[j]
if (meth.id === methodID) {
if (report)
this.project.classes[i].methods[j].latestReport = report
if (executionStatus)
this.project.classes[i].methods[j].executionStatus =
executionStatus
return
}
}
}
}
},
prettyName: function (name) {
const split = name.split('.')
return split[split.length - 1]
}
},
components: {
ClassView: ClassView
}
}
</script>
<style scoped></style>
project.classes
数据发生更改时,方法filteredClasses
都会运行,但返回值ret
没有更新? - Adamret
正在正确修改。Vue只是没有获取该值并更新vm.computed.filteredClasses
。 - Jared Loomisconsole.log(JSON.stringify(ret))
显示了正确的值,但是return ret
却出现了问题。肯定还有其他问题,没有理由会出现这样的问题。当你说 "filteredClasses
在初始缓存后从未更改" 时,你具体指的是什么?在用户界面上吗?最后,你确定你没有一个名为filteredClasses
的方法或数据属性吗? - Adam