- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在学习一个简单的教程,出于某种原因,我的 2 个 View 突变(addCard 和 addList)工作正常......但是,我的第三个突变(editCard)似乎在 Vue 中不起作用。当我单击卡片时,会弹出一个停留点,您可以在其中编辑名称...保存后,它会正确保存在 Rails 中,但不会立即在浏览器中更新。您必须刷新页面才能看到更改。我最初认为这是与 Vuex 和 Rails-ujs 的冲突,但为什么 2 个突变不起作用而第 3 个突变不起作用?在此感谢 Vue 专家的任何帮助...
应用程序/javascript/app.vue
<template>
<div id="app" class="row">
<div class="col-12">
<!-- Button trigger modal -->
<button type="button" data-toggle="modal" data-target="#exampleModal">New List</button>
<!-- Bootstrap Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<textarea ref="message" v-model="message" class="form-control mb-1">
</textarea>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button v-on:click="createList" class="btn btn-secondary">Add</button>
</div>
</div>
</div>
</div>
</div><br/><br/>
<hr /><hr />
<div class="col-2">
<div class="list">
<a v-if="!editing" v-on:click="startEditing">
<h1 style="padding: 20px 20px;">
<span style="font-style: italic;">+ Add a List</span>
</h1>
</a>
<textarea v-if="editing" ref="message" v-model="message" class="form-control mb-1">
</textarea>
<button v-if="editing" v-on:click="createList" class="btn btn-secondary">Add</button>
<a v-if="editing" v-on:click="editing=false">cancel</a>
</div>
</div>
<list v-for="(list, index) in lists" :list="list"></list>
</div>
</template>
<script>
import list from 'components/list'
export default {
components: { list },
data: function() {
return {
editing: false,
message: "",
}
},
computed: {
lists: {
get() {
return this.$store.state.lists;
},
set(value) {
this.$store.state.lists = value
},
},
},
methods: {
startEditing: function () {
this.editing = true
this.$nextTick(() => { this.$refs.message.focus() })
},
createList: function() {
var data = new FormData // -> {}
data.append("list[name]", this.message)// -> { "list[name]" => this.message }
Rails.ajax({
url: "/lists",
type: "POST",
data: data,
dataType: "json",
beforeSend: () => true,// 2xx, 3xx (SUCCESS), 4xx, 5xx (ERROR)
success: (data) => {
this.$store.commit('addList', data)
this.message = ""
this.editing = false
$('#exampleModal').modal('hide');
return false;
}
});
}
}
}
</script>
<style scoped>
.list {
background-color: #e2e4e6;
padding: 8px;
border-radius: 3px;
margin-bottom: 8px;
}
.card {
}
p {
font-size: 2em;
text-align: center;
}
</style>
应用程序/javascript/packs/application.js
import Vue from 'vue/dist/vue.esm'
import Vuex from 'vuex'
// import BootstrapVue from 'bootstrap-vue' || These are for bootstrap vue removing for now
import App from'../app.vue'
import TurbolinksAdapter from 'vue-turbolinks'
// import 'bootstrap/dist/css/bootstrap.css'; || These are for bootstrap vue removing for now
// import 'bootstrap-vue/dist/bootstrap-vue.css'; || These are for bootstrap vue removing for now
// Vue.use(BootstrapVue); || These are for bootstrap vue removing for now
Vue.use(Vuex)
Vue.use(TurbolinksAdapter)
window.store = new Vuex.Store({
state: {
lists: []
},
mutations: {
addList(state, data) {
state.lists.unshift(data)
},
addCard(state, data) {
const index = state.lists.findIndex(item => item.id == data.list_id)
state.lists[index].cards.push(data)
},
editCard(state, data) {
const list_index = state.lists.findIndex((item) => item.id == data.list_id)
const card_index = state.lists[list_index].cards.findIndex((item) => item.id == data.id)
state.lists[list_index].cards.splice(card_index, 1, data)
},
}
})
document.addEventListener("turbolinks:load", function() {
var element = document.querySelector("#boards")
if (element != undefined) {
window.store.state.lists = JSON.parse(element.dataset.lists)
const app = new Vue({
el: element,
store: window.store,
template: "<App />",
components: { App }
})
}
});
应用程序/javascript/components/card.vue
<template>
<div>
<div @click="editing=true" class="card card-body mb-3">
{{card.name}}
</div>
<div v-if='editing' class="modal-backdrop show"></div>
<div v-if='editing' @click="closeModal" class="modal show" style="display: block">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">{{ card.name }}</h5>
</div>
<div class="modal-body">
<input v-model="name" class="form-control"></input>
</div>
<div class="modal-footer">
<button @click="save" type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['card', 'list'],
data: function () {
return {
editing: false,
name: this.card.name,
}
},
methods: {
closeModal: function(event) {
if (event.target.classList.contains("modal")) {
this.editing = false
}
},
save: function() {
var data = new FormData
data.append("card[name]", this.name)
Rails.ajax({
url: `/cards/${this.card.id}`,
type: "PATCH",
data: data,
dataType: "json",
beforeSend: function() { return true },
success: (data) => {
this.$store.commit('editCard', data)
this.editing = false
}
})
},
}
}
</script>
<style scoped>
</style>
应用/javascript/components/list.vue
<template>
<div class="col-2">
<div class="list">
<h6>{{ list.name }}</h6>
<card v-for="card in list.cards" :card="card" :list="list"></card>
<div class="card card-body">
<a v-if="!editing" v-on:click="startEditing">Add a Card</a>
<textarea v-if="editing" ref="message" v-model="message" class="form-control mb-1"></textarea>
<button v-if="editing" v-on:click="createCard" class="btn btn-secondary">Add</button>
<a v-if="editing" v-on:click="editing=false">cancel</a>
</div>
</div>
</div>
</template>
<script>
import card from 'components/card'
export default {
components: { card },
props: ["list"],
data: function () {
return {
editing: false,
message: ""
}
},
methods: {
startEditing: function () {
this.editing = true
this.$nextTick(() => { this.$refs.message.focus() })
},
createCard: function() {
var data = new FormData
data.append("card[list_id]", this.list.id)
data.append("card[name]", this.message)
Rails.ajax({
url: "/cards",
type: "POST",
data: data,
dataType: "json",
beforeSend: function() { return true },
success: (data) => {
this.$store.commit('addCard', data)
this.message = ""
this.$nextTick(() => { this.$refs.message.focus() })
}
});
}
}
}
</script>
<style scoped>
.list {
background-color: #e2e4e6;
padding: 8px;
border-radius: 3px;
margin-bottom: 8px;
}
.btn.btn-secondary {
width: 75px;
}
</style>
更新:当我编辑和保存卡片时,我已经根据要求更新了控制台和终端日志。
终端日志:
Started GET "/lists/" for 127.0.0.1 at 2018-04-24 21:51:47 -0500
Processing by ListsController#index as HTML
Rendering lists/index.html.erb within layouts/application
List Load (11.3ms) SELECT "lists".* FROM "lists" ORDER BY "lists"."position" DESC
Card Load (0.1ms) SELECT "cards".* FROM "cards" WHERE "cards"."list_id" = ? ORDER BY "cards"."position" ASC [["list_id", 235]]
Card Load (0.1ms) SELECT "cards".* FROM "cards" WHERE "cards"."list_id" = ? ORDER BY "cards"."position" ASC [["list_id", 234]]
Card Load (0.1ms) SELECT "cards".* FROM "cards" WHERE "cards"."list_id" = ? ORDER BY "cards"."position" ASC [["list_id", 233]]
Card Load (0.1ms) SELECT "cards".* FROM "cards" WHERE "cards"."list_id" = ? ORDER BY "cards"."position" ASC [["list_id", 232]]
Card Load (0.1ms) SELECT "cards".* FROM "cards" WHERE "cards"."list_id" = ? ORDER BY "cards"."position" ASC [["list_id", 231]]
Rendered lists/index.html.erb within layouts/application (17.8ms)
Rendered shared/_head.html.erb (203.0ms)
Rendered shared/_navbar.html.erb (0.6ms)
Rendered shared/_notices.html.erb (0.3ms)
Completed 200 OK in 370ms (Views: 346.5ms | ActiveRecord: 11.9ms)
Started PATCH "/cards/106" for 127.0.0.1 at 2018-04-24 21:51:59 -0500
Processing by CardsController#update as JSON
Parameters: {"card"=>{"name"=>"Card C30006"}, "id"=>"106"}
Card Load (0.2ms) SELECT "cards".* FROM "cards" WHERE "cards"."id" = ? LIMIT ? [["id", 106], ["LIMIT", 1]]
(0.0ms) begin transaction
List Load (0.1ms) SELECT "lists".* FROM "lists" WHERE "lists"."id" = ? LIMIT ? [["id", 231], ["LIMIT", 1]]
SQL (0.2ms) UPDATE "cards" SET "name" = ?, "updated_at" = ? WHERE "cards"."id" = ? [["name", "Card C30006"], ["updated_at", "2018-04-25 02:51:59.753283"], ["id", 106]]
(1.7ms) commit transaction
Rendering cards/show.json.jbuilder
Rendered cards/_card.json.jbuilder (0.6ms)
Rendered cards/show.json.jbuilder (2.5ms)
Completed 200 OK in 28ms (Views: 21.7ms | ActiveRecord: 2.2ms)
浏览器控制台:
{id: 106, list_id: 231, name: "Card C30006", position: 3, created_at: "2018-04-24T20:39:06.150Z", …}
created_at:(...)
id:(...)
list_id:(...)
name:(...)
position:(...)
updated_at:(...)
url:(...)
__ob__:Observer
dep:Dep {id: 86, subs: Array(0)}
value:{…}
vmCount:0
__proto__:Object
get created_at:ƒ reactiveGetter()
set created_at:ƒ reactiveSetter(newVal)
get id:ƒ reactiveGetter()
set id:ƒ reactiveSetter(newVal)
get list_id:ƒ reactiveGetter()
set list_id:ƒ reactiveSetter(newVal)
get name:ƒ reactiveGetter()
set name:ƒ reactiveSetter(newVal)
get position:ƒ reactiveGetter()
set position:ƒ reactiveSetter(newVal)
get updated_at:ƒ reactiveGetter()
set updated_at:ƒ reactiveSetter(newVal)
get url:ƒ reactiveGetter()
set url:ƒ reactiveSetter(newVal)
__proto__:Object
更新 2:(添加 Vuex 面板输出)
最佳答案
Vue 对可以自动检测到的数据更新有警告:https://v2.vuejs.org/v2/guide/list.html#Caveats
另外, react 规则有一些信息:https://vuex.vuejs.org/en/mutations.html#mutations-follow-vues-reactivity-rules
我认为警告页面实际上反射(reflect)了您的情况。引用:
Due to limitations in JavaScript, Vue cannot detect the following changes to an array:
When you directly set an item with the index, e.g.
vm.items[indexOfItem] = newValue
When you modify the length of the array, e.g.vm.items.length = newLength
To overcome caveat 1, both of the following will accomplish the same as
vm.items[indexOfItem] = newValue
, but will also trigger state updates in the reactivity system:
// Vue.set Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice vm.items.splice(indexOfItem, 1, newValue)
基于此,我会尝试将您的代码更新为:
editCard(state, data) {
const list_index = state.lists.findIndex((item) => item.id == data.list_id)
const card_index = state.lists[list_index].cards.findIndex((item) => item.id == data.id)
var updata = state.lists[list_index].cards[card_index] = data;
state.lists.splice(list_index, 1, updata);
将拼接移动到列表的顶层现在应该会触发更新。
请注意,如果您有任何反馈,我很乐意适当更新此答案。
关于ruby-on-rails - Vue.JS 和 Rails-UJS/Jquery-UJS 冲突 - Vuex 突变不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49933491/
我的工作是将每条记录写入 Hadoop 映射中的 DynamoDB。 我无法使用具有 httpclient-4.2.5.jar 和 httpcore-4.2.5.jar 的 Hadoop 2.6 运行
我在 JavaScript 中嵌套了循环开关,例如: for (var i = 0; i < checkBoxIds.length; i++) { if ($('#' + checkB
我有一个文件夹被重命名的分支。现在我正在尝试合并从主干到这个分支的更改,但是在主干中修改的文件仍然在原始文件夹名称下,因此 svn 引发了树冲突。我该如何解决这个问题? 该文件夹已使用 svn ren
我在使用 jquery 暴露插件和 Masked 输入插件时遇到了问题。问题是它们都占用 $.mask 函数,从而导致冲突。但我非常需要这两个插件一起工作。我会将其中一个中的 $.mask 重命名为.
我正在尝试为我所有的 INPUT 元素做一个简单的 :focus 效果,就像这样: INPUT:focus { border-color: orange; } 这很好用,直到我将这段 CSS 添加到样
我是 javascript 的新手。 在 wordpress 上工作,我在自定义 js 中为我的主题输入了以下函数: document.getElementsByName("empty_cart")[
为什么有些 javascript 会与其他的发生冲突?我的意思是我一直在为图片库使用 javascript 代码,然后尝试在 jquery 中获取文本水印。为什么在使用 jquery 之后,画廊完全消
是否可以根据已知的输入值创建 MD5 碰撞? 所以例如我有输入字符串 abc与 MD5 900150983cd24fb0d6963f7d28e17f72 . 现在我想将字节添加到字符串 def获得相同
我在我的项目中使用原型(prototype): NodeParser.prototype.getChildren = function(parentContainer) { return fl
根据我对 merge 冲突的理解,当两个人更改了同一文件和/或修改了该文件中的同一行时,就会发生 merge 冲突。所以当我做一个 git pull origin master 我期望 merge 冲
iPad 上 Mobile Safari 中的 HTML5 模板。带 iScroll 的 Div 工作正常。 if/else 语句中还包含一个 jQuery 函数。该函数测试用户是否在 iScroll
我一直在尝试使 2 个脚本(1 个 mootol 和 1 个 jquery)在同一页面上工作,但没有成功。我一直在研究许多论坛等,但我仍然无法使这两个脚本同时工作。 这就是它在我的标题中的样子: /w
我想克隆带标题的问号。一切正常,但是当我将鼠标悬停在新问号上时,第一个问号上会出现工具提示。有什么想法吗? 我正在使用 jQuery 和醉酒的工具提示。 Demo here click here
好吧,我已经在一个 friend 的网站上工作了一段时间了。我的编码技能......值得怀疑,而且我遇到了很多问题。 目前我网站上的 jQuery 停止工作了,我找不到原因,并且我已尽一切努力让它工作
我想使用一个文件来保存所有#define 和常量:示例 #ifndef CONSTANTS_H_ #define CONSTANTS_H_ #include //OVERALL DEFS
我在我的表单中的所有 HTML 下都有一些验证码,这似乎阻止了我的复选框验证码的工作,一旦我在我的 HTML 下的代码周围添加/* */(使其不活动),我就得出了这个结论) 复选框验证代码开始正常工作
我是新手。我的页面上有两个 javascript/jquery。如果我使用第一个脚本,第二个脚本将不起作用。如果我删除第一个脚本,第二个脚本就可以正常工作。我不知道如何解决这个问题。我知道有一个“无冲
我是 Bison 新手,在处理 Shift/Reduce 冲突时遇到了麻烦... 我正在为C语言编写语法规则:ID是标识变量的标记,我编写此规则是为了确保即使将标识符写在括号中,也可以考虑它。 id
我目前正在使用 LibGdx 开发我的第一个 Android 游戏项目。这是一款 2D 迷宫游戏,您可以使用触摸输入从其中一个入口到其中一个导出“画出”一条线。世界本身是一个 TiledMap,目前仅
我正在尝试通过 javascript 完成表单验证,并在 #form# 标记中放置一个要执行的 .py 文件操作。但问题是,当我提交数据后,它不会重定向到 .py 操作。所以我摆脱了 preventd
我是一名优秀的程序员,十分优秀!