Bonjour,
J'ai créé un petit composant autocomplete sur un input, avec une props en dur j'arrive à le charger mais je cherche maintenant à l'initialiser sur le resultat d'un appel ajax.
J'ai procédé comme ça:
import axios from 'axios';
export default {
name: 'autocomplete',
props: {
isAsync: {
type: Boolean,
required: false,
default: false,
},
},
data() {
return {
items: [],
isOpen: false,
results: [],
search: '',
isLoading: false,
arrowCounter: 0,
};
},
methods: {
onChange() {
// Let's warn the parent that a change was made
this.$emit('input', this);
// Is the data given by an outside ajax request?
if (this.isAsync) {
this.isLoading = true;
} else {
// Let's our flat array
this.filterResults();
this.isOpen = true;
}
},
filterResults() {
// first uncapitalize all the things
this.results = this.items.filter((item) => {
return item.toLowerCase().indexOf(this.search.toLowerCase()) > -1;
});
},
setResult(result) {
this.search = result;
this.isOpen = false;
},
onArrowDown(evt) {
if (this.arrowCounter < this.results.length) {
this.arrowCounter = this.arrowCounter + 1;
}
},
onArrowUp() {
if (this.arrowCounter > 0) {
this.arrowCounter = this.arrowCounter -1;
}
},
onEnter() {
this.search = this.results[this.arrowCounter];
this.isOpen = false;
this.arrowCounter = -1;
},
handleClickOutside(evt) {
if (!this.$el.contains(evt.target)) {
this.isOpen = false;
this.arrowCounter = -1;
}
}
},
watch: {
items: function (val, oldValue) {
// actually compare them
if (val.length !== oldValue.length) {
this.results = val;
this.isLoading = false;
}
},
},
mounted() {
document.addEventListener('click', this.handleClickOutside)
axios.get(`http://jsonplaceholder.typicode.com/posts`)
.then(function(response){
for (var i = 0; i < response.data.length; i++) {
console.log(this);
//this.items.push(response.data[i].title)
}
})
},
destroyed() {
document.removeEventListener('click', this.handleClickOutside)
}
};
</script>
mais le console.log(this); me retourne un undefined. comment initialiser et mettre à jour cette propriété ?
Salut, ce n'est pas un problème de VueJS mais de scope en JS. Lorsque tu définies une nouvelle fonction avec function() {}
, tu crées un nouveau scope. Il faut donc binder ton scope avec le scope global. Pour cela tu as deux solutions:
1) utiliser Function.prototype.bind()
https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Function/bind. Valide ES5.
axios.get(`http://jsonplaceholder.typicode.com/posts`)
.then(function(response){
for (var i = 0; i < response.data.length; i++) {
console.log(this);
//this.items.push(response.data[i].title)
}
}.bind(this))
2) Utiliser une arrow function https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions, qui garde le scope parent. Attention, c'est une nouveauté de ES6, si tu vises des anciens navigateurs, il faudra utiliser un compilateur pour compiler le code en ES5.
axios.get(`http://jsonplaceholder.typicode.com/posts`)
.then((response) => {
for (var i = 0; i < response.data.length; i++) {
console.log(this);
//this.items.push(response.data[i].title)
}
})
Je t'invite à lire ceci : https://hackernoon.com/understanding-javascript-the-this-keyword-4de325d77f68