私は見つけることができるすべての同様の投稿を見てきましたが、私の問題を解決する答えはありません。具体的には、idが "table"のテーブルを更新しません。このインスタンスでVueJSがDOMの更新を停止する原因は何ですか?
HTML:
<section id="body">
<div class="container-fluid">
<div class="row">
<div class="col-xs-12">
<div class="panel panel-primary">
<div class="panel-heading" id="panel">
<div class="row">
<div class="col-sm-12">
<h3 class="panel-title">Filters</h3>
</div>
</div>
</div>
<div class="panel-body" id="panel-body">
<div class="row">
<div class="col-sm-12">
<form id="filterForm" class="form-horizontal">
<div class="form-group">
<div class="col-sm-12">
<label class="control-label" for="focusedInput">Category:</label>
<select id="category" class="js-example-basic-single form-control">
<option value="">Any</option>
<option v-for="category in categories" value="category.categoryTitle">
{{category.categoryTitle}}</option>
</select>
</div>
</div>
<div class="form-inline row">
<div class="col-sm-12">
<label class="control-label" style="margin-right:20px;">Air Date:</label>
<div style="width:35%" class="form-group">
<div class='input-group date' id='datetimepicker1'>
<input type='text' class="form-control" v-model="airDate"/>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<label class="control-label">Show Number:</label>
<input style="width:35%" class="form-control" type="number" id="showNumber" v-model="showNumber">
</div>
</div>
<div class="form-inline row">
<div class="col-sm-12">
<label class="control-label">Question contains:</label>
<input style="width:35%" class="form-control" type="text" v-model="questionText">
<label class="control-label">Dollar Value:</label>
<input style="width:35%" class="form-control" type="number" id="showNumber" v-model="dollarValue">
</div>
</div>
</form>
</div>
</div>
<div class="row">
<div class="col-sm-offset-9 col-sm-3" style="margin-top:5px;">
<button type="button" class="btn btn-warning" v-on:click="reset">Reset Filters</button>
<button type="button" class="btn btn-primary" v-on:click="filter">Filter</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="panel panel-primary" id="tableCard" style="margin-bottom:20px; margin-top:40px;">
<div class="panel-heading">
<div class="row">
<div class="col-sm-10">
<h3 class="panel-title">Jeopardy Questions</h3>
</div>
<div class="col-sm-2">
<span id="totalQuestionsSpan">Total Entries: {{entries.length}} entries</span>
</div>
</div>
</div>
<div class="panel-body" style="padding-top:45px;">
<div class="wrapper">
<table id="tableScroll" class="table table-striped table-fixed">
<thead style="background-color:white;">
<tr>
<th style="cursor:pointer; min-width: 110px;">
Question
<span v-if="questionSort == 1" id="questionUp">▲</span>
<span v-else-if="questionDown == -1" id="questionDown">▼</span>
</th>
<th style="cursor:pointer; min-width: 120px; ">
Answer
<span v-if="answerSort == 1" id="answerUp">▲</span>
<span v-else-if="answerDown == -1" id="answerDown">▼</span>
</th>
<th style="cursor:pointer; min-width: 80px;">
Value
<span v-if="valueSort == 1" id="valueUp">▲</span>
<span v-else-if="valueDown == -1" id="valueDown">▼</span>
</th>
<th style="cursor:pointer; min-width: 80px;">
Show Number
<span v-if="showNumberSort == 1" id="showNumberUp">▲</span>
<span v-else-if="showNumberDown == -1" id="showNumberDown">▼</span>
</th>
<th style="cursor:pointer; min-width: 80px;">
Category
<span v-if="categorySort == 1" id="categoryUp">▲</span>
<span v-else-if="categoryDown == -1" id="categoryDown">▼</span>
</th>
<th style="cursor:pointer; min-width: 80px;">
Air Date
<span v-if="airDateSort == 1" id="airDateUp">▲</span>
<span v-else-if="airDateDown == -1" id="airDateDown">▼</span>
</th>
</tr>
</thead>
<tbody id="table">
<tr v-for="entry in entries">
<td>{{entry.questionText}}</td>
<td>{{entry.answerText}}</td>
<td>{{entry.dollarValue}}</td>
<td>{{entry.showNumber}}</td>
<td>{{entry.categoryTitle}}</td>
<td>{{entry.airDate}}</td>
</tr>
<tr v-if="entries.length == 0">
<td colspan="6" style="text-align: center;"> No entries to display </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
JS
var app = new Vue({
el: '#body',
data: {
loggedIn: false,
questionSort: 0,
answerSort: 0,
valueSort: 0,
showNumberSort: 0,
categorySort: 0,
airDateSort: 0,
entries: [],
url: "/questions",
categories: [],
// form model data
categoryTitle: '',
airDate: '',
questionText: '',
dollarValue: '',
showNumber: '',
},
mounted: function() {
$.get("/api/categories", function(result) {
Vue.set(app, "categories", result.data);
$('.js-example-basic-single').select2();
}, "json").fail(function(err) {
showErrorMessage(err.responseJSON.message_prettified);
});
},
methods: {
filter : function() {
var queryParams = "?";
var params = 0;
app.categoryTitle = $('#category :selected').text().trim();
if (typeof app.categoryTitle !== "undefined" && app.categoryTitle != null) {
params++;
queryParams += "categoryTitle=" + app.categoryTitle
}
if (app.airDate.length > 0) {
params++;
if (params > 0) {
queryParams += "&";
}
queryParams += "airDate=" + app.airDate
}
if (app.questionText.length > 0) {
params++;
if (params > 0) {
queryParams += "&";
}
queryParams += "questionText=" + app.questionText
}
if (app.dollarValue.length > 0) {
params++;
if (params > 0) {
queryParams += "&";
}
queryParams += "dollarValue=" + app.dollarValue
}
if (app.showNumber.length > 0) {
params++;
if (params > 0) {
queryParams += "&";
}
queryParams += "showNumber=" + app.showNumber
}
if (queryParams.length == 1) {
queryParams = "";
}
var url = "/questions"
var URL = url + queryParams;
$.get(URL, result => {
Vue.set(app, "entries", result.data);
app.$forceUpdate();
}, "json").fail(function(err) {
showErrorMessage(err.responseJSON.message_prettified);
}).always(function() {
$("#loader").addClass("toggled");
});
}
}
});
現在の行動:
は/API /カテゴリへのAJAX呼び出しが正しく、私はカテゴリを選択することができ、DOMのドロップダウンを更新。アプリケーションがマウントされると、表が更新され、colspan 6「表示する項目がありません」というセルが表示されます。ただし、フィルタ要求が送信されて返された後、テーブルは更新されたデータを反映するように更新されません(コンソールでチェックされたときにデータが正しく変更されたとして表示されます)。
期待される動作:
AJAX呼び出しクエリのparams解決さとの質問/へとテーブルの更新は、変更を反映するために、アプリ内のエントリのデータフィールドを更新します。
未遂修正:
探検$ forceUpdate、$セット、Vue.set、および手動でループに使用して配列を上書きします。
編集:
スヌーピングともVueXの統合の多くを行った後(@WaldemarIceによって以下示唆されているように)助けたが、関係なく、私がきた、私のミニプログラムの全体的なコードの構造を改善しましたたかもしれません解決策に到着しました。
Laracast上のこの投稿は、私はおそらく、データに問題があったかどうかを疑問に思う行わ:その後、私は問題を実現させhttps://laracasts.com/discuss/channels/vue/v-for-loop-rendering-keeps-throwing-undefined-error
は、ここでのコード行にあった:
原因となった<option v-for="category in categories" value="category.categoryTitle">
{{category.categoryTitle}}</option>
value = category.categoryTitleのカテゴリは、ライフサイクルの後半まで定義されていなかったため、問題が発生しました。私はそれをv-bindに変更しました:value = "category.categoryTitle"そしてJSを更新して今すぐ動作させました。 @Kaicuiの投稿に関するフォローアップの議論で投稿したTypeErrorは、Vueにデータの反応性を失わせていました。私がその問題を解決すると、Vueは再び適切に反応し始めました。
更新HTML:
<section id="body">
<div class="container-fluid">
<div class="row">
<div class="col-xs-12">
<div class="panel panel-primary">
<div class="panel-heading" id="panel">
<div class="row">
<div class="col-sm-11">
<h3 class="panel-title">Filters</h3>
</div>
<div class="col-sm-1">
<i id="toggleFilter" class="fa fa-chevron-down filter-collapsed" style="cursor:pointer; display:none;" aria-hidden="true"></i>
<i id="toggleFilter" class="fa fa-chevron-up filter-collapsed" aria-hidden="true" style="cursor:pointer;"></i>
</div>
</div>
</div>
<div class="panel-body" id="panel-body">
<div class="row">
<div class="col-sm-12">
<form id="filterForm" method="GET" action="/questions" class="form-horizontal">
<div class="form-inline">
<div class="col-sm-12" style="margin-bottom:15px;">
<input type="hidden" name="categoryTitle" id="categoryTitleHidden">
<label class="control-label" for="focusedInput">Category:</label>
<select style="width:90%; height:120% !important;" v-model="categorySelect" id="category" class="js-example-basic-single form-control">
<option value="">Any</option>
<option v-for="category in categories" v-bind:value="category.categoryTitle">
{{category.categoryTitle}}</option>
</select>
</div>
</div>
<div class="form-inline">
<div class="col-sm-12" style="margin-bottom:15px;">
<label class="control-label" style="margin-right:20px;">Air Date:</label>
<div style="width:35%; margin-right:10px" class="form-group">
<div style="width:100%" class='input-group date' id='datetimepicker1'>
<input type='text' class="form-control" name="airDate"/>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
<label class="control-label">Show Number:</label>
<input style="width:35%" class="form-control" type="number" id="showNumber" name="showNumber">
</div>
</div>
<div class="form-inline">
<div class="col-sm-12">
<label class="control-label">Question contains:</label>
<input style="width:35%" class="form-control" type="text" id="questionText" name="questionText">
<label class="control-label">Dollar Value:</label>
<input style="width:35%" class="form-control" type="number" id="dollarValue" name="dollarValue">
</div>
</div>
</form>
</div>
</div>
<div class="row">
<div class="col-sm-offset-9 col-sm-3" style="margin-top:5px;">
<button type="button" class="btn btn-warning" v-on:click="reset">Reset Filters</button>
<button type="button" class="btn btn-primary" v-on:click="filter">Filter</button>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="panel panel-primary" id="tableCard" style="margin-bottom:20px; margin-top:40px;">
<div class="panel-heading">
<div class="row">
<div class="col-sm-10">
<h3 class="panel-title">Jeopardy Questions</h3>
</div>
<div class="col-sm-2">
<span id="totalQuestionsSpan">Total Entries: {{entryCount}} entries</span>
</div>
</div>
</div>
<div class="panel-body" style="padding-top:45px;">
<div class="wrapper">
<table id="tableScroll" class="table table-striped table-fixed">
<thead style="background-color:white;">
<tr>
<th style="cursor:pointer; min-width: 110px;">
Question
</th>
<th style="cursor:pointer; min-width: 120px; ">
Answer
</th>
<th style="cursor:pointer; min-width: 80px;">
Value
</th>
<th style="cursor:pointer; min-width: 80px;">
Show Number
</th>
<th style="cursor:pointer; min-width: 80px;">
Category
</th>
<th style="cursor:pointer; min-width: 80px;">
Air Date
</th>
</tr>
</thead>
<tbody id="table">
<tr v-if="entriesValid" v-for="entry in entries">
<td>{{entry.questionText}}</td>
<td>{{entry.answerText}}</td>
<td>{{entry.dollarValue}}</td>
<td>{{entry.showNumber}}</td>
<td>{{entry.categoryTitle}}</td>
<td>{{entry.airDate}}</td>
</tr>
<tr v-if="!entriesValid">
<td colspan="6" style="text-align: center;"> No entries to display </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<div style="position: absolute; left: 45%; top:25%; z-index:3;">
<i id="loader" class="fa fa-circle-o-notch fa-spin fa-5x fa-fw toggled" style="z-index:3"></i>
</div>
</section>
更新JS
Vue.use(Vuex)
Vue.config.debug = false;
Vue.config.silent = true;
var URL;
const store = new Vuex.Store({
state: {
loggedIn: false,
// ordering data
questionSort: 0,
answerSort: 0,
valueSort: 0,
showNumberSort: 0,
categorySort: 0,
airDateSort: 0,
// server related ata
entries: [],
url: "/questions",
categories: [{
categoryTitle: "Test",
}],
},
mutations: {
categories (state, data) {
state.categories = data;
},
entries (state, data) {
console.log(data);
state.entries = data;
console.log(state.entries)
}
},
actions: {
fetchCategories ({ commit }) {
$("#loader").removeClass("toggled");
$.get("/api/categories", function(result) {
commit('categories', result.data);
}, "json")
.fail(function(err) {
if (err.status == 0) {
showErrorMessage("Network Problem");
}
else {
showErrorMessage(err.responseJSON.message_prettified);
}
}).always(function() {
$("#loader").addClass("toggled");
});
},
},
});
var app = new Vue({
el: '#body',
store: store,
data: {
categorySelect: "",
},
mounted: function() {
store.dispatch("fetchCategories").then(() => {
$('.js-example-basic-single').select2();
});
},
computed: {
categories: function() {
return store.state.categories;
},
entryCount: function() {
if (store.entries) {
if (typeof store.entries.length !== "undefined") {
return store.entries.length;
}
else {
return 0;
}
}
else {
return 0;
}
},
entriesValid: function() {
if (store.state.entries) {
if (typeof store.state.entries.length !== "undefined" && store.state.entries.length > 0) {
return true;
}
else {
return false;
}
}
else {
return false;
}
},
entries: function() {
return store.state.entries;
},
loggedIn: function() {
return store.state.loggedIn;
},
},
methods: {
reset: function() {
$('.js-example-basic-single').val('').trigger('change');
$("#datetimepicker1").datetimepicker("clear");
$("#categoryTitleHidden").val("");
$("#showNumber").val("");
$("#questionText").val("");
$("#showNumber").val("");
$("#dollarValue").val("");
},
filter : function() {
var value = $('#category :selected').text().trim();
if (value !== "Any") {
$("#categoryTitleHidden").val(value);
}
else {
$("#categoryTitleHidden").val("");
}
var options = {
success: function(responseText, statusText, xhr, $form) {
store.commit("entries", JSON.parse(xhr.responseText).data)
}
};
$("#filterForm").ajaxSubmit(options);
}
}
});
私は直接割り当て(app.entries = result.data)を試みましたが、それもうまくいきませんでした。私は、Vue.set関数がDOMの強制的な更新を引き起こすかもしれないという読書を行っていました(うまくいきませんでした)。 代わりに何をお勧めしますか? – Pedro
Vueインスタンスのルートデータオブジェクトにプロパティを設定することはできないため、Vuexを使用することができます。 – WaldemarIce
私はVuexに一発のショットを与え、問題が解決するかどうかを確認します。提案していただきありがとうございます!一度私はそれを与えた私はチェックインします。 – Pedro