Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么';t Vuejs寄存器是否启用或禁用我的按钮?_Javascript_Vue.js - Fatal编程技术网

Javascript 为什么';t Vuejs寄存器是否启用或禁用我的按钮?

Javascript 为什么';t Vuejs寄存器是否启用或禁用我的按钮?,javascript,vue.js,Javascript,Vue.js,我正在创建一个简单的Vuejs网站,您可以在其中编写会议记录。加载后,它会从服务器上获取会议记录并显示它们。然后,当用户写入内容时,他可以单击“保存”按钮,将文本保存到服务器。将注释保存到服务器时,需要禁用“保存”按钮,并显示一条文字“保存”。当用户再次开始写入文本时,应再次启用按钮并再次显示“保存”。这是一个相当基本的功能,我想说,但我有麻烦 这是我的文本区和保存按钮: <textarea v-model="selectedMeeting.content" ref="meetingCon

我正在创建一个简单的Vuejs网站,您可以在其中编写会议记录。加载后,它会从服务器上获取会议记录并显示它们。然后,当用户写入内容时,他可以单击“保存”按钮,将文本保存到服务器。将注释保存到服务器时,需要禁用“保存”按钮,并显示一条文字“保存”。当用户再次开始写入文本时,应再次启用按钮并再次显示“保存”。这是一个相当基本的功能,我想说,但我有麻烦

这是我的文本区和保存按钮:

<textarea v-model="selectedMeeting.content" ref="meetingContent"></textarea>
<button v-on:click="saveMeeting" v-bind:disabled="meetingSaved">
    {{ saveMeetingButton.saveText }}
</button>
创建后,我从服务器获取会议记录:

created() {
    axios.get('/ajax/meetings')
        .then(response => {
            this.meetings = response.data;
            this.selectedMeeting = this.meetings[0];
            this.meetingSaved = true;
        });
},
我有一个保存笔记的方法:

methods: {
    saveMeeting: function () {
        axios.post('/ajax/meetings/' + this.selectedMeeting.id, this.selectedMeeting)
            .then(function (response) {
                this.selectedMeeting = response.data;
                console.log('Now setting meetingSaved to true');
                this.meetingSaved = true;
                console.log('Done setting meetingSaved to true');
            });
    },
},
我有一个观察者,以防文本发生变化,它会立即保存文本(这会随我键入的每个字母一起保存,我当然需要更改,但这只是开始

watch: {
    'selectedMeeting.content': function () {
        this.meetingSaved = false;
        console.log('Changed meeting ', new Date());
        this.saveMeeting();
    }
},
如果我现在键入一封信,我会在日志中看到:

Changed meeting  Tue Dec 04 2018 19:14:43 GMT+0100
Now setting meetingSaved to true
Done setting meetingSaved to true
日志与预期的一样,但按钮本身从未被禁用。但是,如果我删除观察者,按钮始终被禁用。即使观察者首先将
this.meeting保存的
设置为
false
,然后将
this.saveMeeting()设置为
将其设置为
true
,添加观察者不会以某种方式禁用按钮

有人知道我做错了什么吗?欢迎提供所有提示

[编辑]


这里是整个页面的粘贴:

您有一些事情需要改变

首先,
data
属性应该是一个返回对象的函数:

data() {
    return {
        selectedMeeting: {
            content: null
        },
        meetings: [],
        meetingSaved: true,
        saveMeetingButton: { 
            saveText: 'Save Meeting',
            savedText: 'Saved',
            disabled: true
        },
    };
}
这样Vue就可以将属性正确绑定到每个实例

另外,
selectedMeeting
content
属性在初始渲染中不存在,因此Vue没有在属性上添加适当的“包装器”以让内容知道它已更新

另一方面,可以使用
Vue.set

接下来,我建议您使用
async/await
作为您的承诺,因为这样更容易遵守

async created() {
    const response = await axios.get('/ajax/meetings');
    this.meetings = response.data;
    this.selectedMeeting = this.meetings[0];
    this.meetingSaved = true;
},
对于您的方法,我还将编写为async/await。您还可以使用Vue修饰符,如单击时使用
once
on click,仅在之前没有请求的情况下调用api(考虑快速双击)

代码的其余部分看起来没问题

总结一下,主要问题是在
data
函数中没有返回对象,并且没有反应性地绑定属性

接下来,您将希望对触发api调用的文本输入进行
debounce
,并限制调用

this.meetingSaved = true;
引用的是
axios
对象。在调用外部引用vue对象,然后使用它。使用
jQuery.ajax()时也会发生同样的情况


在您的watcher中,您正在调用
this.saveMeeting()
,这意味着您每次在
文本区域键入字符时都将保存和禁用该按钮。这是您想要的吗?顺便说一句,这里有一个codesandbox,显示您可以启用和禁用该按钮:您能检查控制台中是否有任何错误吗?如果在渲染过程中有任何错误,这将意味着它不会提供错误n更新DOM,使其看起来好像什么都没有发生。我的最佳选择是为'this.selectedMeeting'分配一个
未定义的
值。感谢您的建议。不幸的是,按照您的建议将数据更改为函数并不能解决我的问题。我在问题中添加了整个页面的粘贴。这里也是:没有你有什么新的想法可以告诉你问题是什么?你的pastebin没有数据功能,而且我认为你可能想在$nextTick调用中包装承诺,这样api调用就不会阻塞UI。你可能禁用了按钮,但在UI重新绑定之前它又被启用了。问题是axios响应中的函数e、 这肯定是错误的。我建议使用async/await来避免“回调”地狱或者如果你不想,Artur的答案会起作用。我知道,我还原了它,因为它没有解决任何问题。所以这显然不是问题。@kramer65你仍然应该这样做,这对Vue很重要。很好的捕捉,我在我的答案中错过了这一点,因为我将它切换为异步。
methods: {
    async saveMeeting () {
        const response = await axios.post('/ajax/meetings/' + this.selectedMeeting.id, this.selectedMeeting);
        this.selectedMeeting = response.data;
        console.log('Now setting meetingSaved to true');
        this.meetingSaved = true;
        console.log('Done setting meetingSaved to true');
    },
},
this.meetingSaved = true;
created() {
    var vm = this;
    axios.get('/ajax/meetings')
        .then(response => {
            vm.meetings = response.data;
            vm.selectedMeeting = vm.meetings[0];
            vm.meetingSaved = true;
        });
},