v-on:更改方法只触发一次get请求(Vue.js)

时间:2017-07-03 06:07:26

标签: javascript ajax vue.js

我正在使用Vue.js和Choices.js javascript插件,我必须通过ajax动态填充两个选择字段的值。

我正在尝试实现的是在页面加载时启动get请求并填充大学选择,并在选择大学选择中的值后,启动新的get请求以填充教职员选择。

发生的事情是,当我第一次选择大学时,一切都会正常进行。例如,如果我选择带有value="1"的大学选项,则会向/faculties?university_id=1发送ajax get请求。控制台日志将打印onChange started,因此我们确定方法正确运行;相应的v-model="selectedUniversity"也在更新。

如果我现在再次更改select字段的值,则不再调用ajax函数,也不会对服务器进行其他请求。 console.log仍会运行,v-model仍在更新中。有谁知道这里发生了什么?

var Choices = require('choices.js');

  module.exports = {
    data: function() {
      return {
        selectedUniversity: '',
        selectedFaculty: '',
        universities: {},
        faculties: {}
      }
    },
    mounted: function () {
      var self = this;
      var universitySelect = new Choices(document.getElementById('university'));

      universitySelect.ajax(function(callback) {
        fetch('/universities')
          .then(function(response) {
            response.json().then(function(data) {
              callback(data, 'id', 'name');

                self.universities = data;
            });
          })
          .catch(function(error) {
            console.log(error);
          });
      });

    },
    methods: {
      onChange: function () {
        console.log("onChange started");
        var self = this;
        var url = '/faculties?university_id=' + self.selectedUniversity;
        var facultySelect = new Choices(document.getElementById('faculty'));
        
        //This part below only runs the first time when the university select  is selected

        facultySelect.ajax(function(callback) {
          fetch(url)
            .then(function(response) {
              response.json().then(function(data) {
                callback(data, 'id', 'name');
                  self.faculties = data;
              });
            })
            .catch(function(error) {
              console.log(error);
            });
        });

      }
    }
  }

标题设置如下:

enter image description here

1 个答案:

答案 0 :(得分:0)

我认为您的请求网址/faculties?university_id=1已缓存,这就是它第一次和第二次工作的原因,响应来自缓存的响应。

fetch API中,设置缓存模式以忽略缓存的响应

fetch(url, {cache: "no-store"}).then(....)

有关cache API的fetch()模式的完整列表, https://hacks.mozilla.org/2016/03/referrer-and-cache-control-apis-for-fetch/

如果上述链接不可用,

获取缓存控制API

此API背后的想法是为fetch指定一个缓存策略,以明确指出应该如何以及何时查询浏览器HTTP缓存。了解HTTP缓存语义以便最有效地使用它们非常重要。网上有很多好文章,比如这篇文章详细描述了这些语义。目前有五种不同的政策可供您选择。

“default”表示在下载资源时使用浏览器的默认行为。浏览器首先查看HTTP缓存内部以查看是否存在匹配的请求。如果有,并且它是新鲜的,它将从fetch()返回。如果它存在但是过时,则向远程服务器发出条件请求,如果服务器指示响应未更改,则将从HTTP缓存中读取该响应。否则,它将从网络下载,HTTP缓存将使用新响应进行更新。

“no-store”表示完全绕过HTTP缓存。这将使浏览器在通往网络的途中不会查看HTTP缓存,并且永远不会将生成的响应存储在HTTP缓存中。使用此缓存模式,fetch()的行为就像没有HTTP缓存一样。

“reload”表示在前往网络的途中绕过HTTP缓存,但使用新下载的响应更新它。这将导致浏览器在通往网络的途中永远不会查看HTTP缓存,而是使用下载的响应更新HTTP缓存。如果合适,未来的请求可以使用更新的响应。

“no-cache”表示总是验证HTTP缓存中的响应,即使浏览器认为它是新鲜的。这将导致浏览器在前往网络的途中在HTTP缓存中查找匹配的请求。如果找到这样的请求,浏览器总是创建一个条件请求来验证它,即使它认为响应应该是新鲜的。如果未找到匹配的缓存条目,则将进行正常请求。下载响应后,将始终使用该响应更新HTTP缓存。

“force-cache”表示如果在缓存中找到匹配的条目,浏览器将始终使用缓存的响应,忽略响应的有效性。因此,即使在缓存中找到了非常旧版本的响应,它也将始终在未经验证的情况下使用。如果在缓存中找不到匹配的条目,浏览器将发出正常请求,并使用下载的响应更新HTTP缓存。

让我们看几个如何使用这些缓存模式的例子。

  // Download a resource with cache busting, to bypass the cache
  // completely.
  fetch("some.json", {cache: "no-store"})
    .then(function(response) { /* consume the response */ });

  // Download a resource with cache busting, but update the HTTP
  // cache with the downloaded resource.
  fetch("some.json", {cache: "reload"})
    .then(function(response) { /* consume the response */ });

  // Download a resource with cache busting when dealing with a
  // properly configured server that will send the correct ETag
  // and Date headers and properly handle If-Modified-Since and
  // If-None-Match request headers, therefore we can rely on the
  // validation to guarantee a fresh response.
  fetch("some.json", {cache: "no-cache"})
    .then(function(response) { /* consume the response */ });

  // Download a resource with economics in mind!  Prefer a cached
  // albeit stale response to conserve as much bandwidth as possible.
  fetch("some.json", {cache: "force-cache"})
    .then(function(response) { /* consume the response */ });