typescript - navCtrl.push nu funcționează în Ionic3


Îmi fac o aplicație cu Ionic care încarcă o imagine în stocarea mea Firebase. Când încărcarea este completă, aplicația ar trebui să redirecționeze utilizatorul către WelcomePage. Încărcarea funcționează, dar dintr-un anumit motiv utilizatorul nu este redirecționat. Aruncă o privire la finalul codului: Consola afișează Uploaded, dar this.navCtrl.push(WelcomePage) nu funcționează.

upload() {
  let storageRef = firebase.storage().ref();

  const filename = "profilePic";

  const imageRef = storageRef.child(`images/${filename}.jpg`).putString(this.profilepicture, firebase.storage.StringFormat.DATA_URL);

  imageRef.on('state_changed', function(snapshot){

    var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
    document.getElementById("percent").innerHTML = "Progresso:" + Math.floor(progress) + "%";   
    console.log('Upload is ' + progress + '% done');
    switch (snapshot.state) {
      case firebase.storage.TaskState.PAUSED:
        console.log('Upload is paused');
        break;
      case firebase.storage.TaskState.RUNNING:
        console.log('Upload is running');
        break;
    }
  }, function(error) {
    // Handle unsuccessful uploads
  }, function() {
    // Handle successful uploads on complete
    console.log('Uploaded');
    this.navCtrl.push(WelcomePage);
  });

 }

Răspuns #1

Cel mai probabil, semnificația lui this este diferită în callback-ul tău. Dacă aceasta este situația, poți fie să pui navCtrl într-o variabilă separată, fie poți folosi funcții săgeată.

Pune navCtrl într-o variabilă separată

Sensul lui this depinde de funcția în care îl folosești. Deoarece callback-urile sunt funcții separate, ele au, de asemenea, propria valoare pentru this. Așadar, în interiorul callback-ului this.navCtrl nu există.

Soluția este să capturezi valoarea de care ai nevoie într-un nume de variabilă unic înainte de apelul de tip callback:

var navCtlr = this.navCtrl;
imageRef.on('state_changed', function(snapshot){
  var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
  document.getElementById("percent").innerHTML = "Progresso:" + Math.floor(progress) + "%";   
  console.log('Upload is ' + progress + '% done');
  switch (snapshot.state) {
    case firebase.storage.TaskState.PAUSED:
      console.log('Upload is paused');
      break;
    case firebase.storage.TaskState.RUNNING:
      console.log('Upload is running');
      break;
  }
}, function(error) {
  // Handle unsuccessful uploads
}, function() {
  // Handle successful uploads on complete
  console.log('Uploaded');
  navCtrl.push(WelcomePage);
});

Folosește funcții săgeată

ES6 adaugă un mod nou de a defini funcții callback folosind o notație cu săgeată groasă. În codul tău, function(error) { poate fi înlocuit cu (error) => {. Pe lângă faptul că este puțin mai scurtă, noua notație menține de fapt semnificația lui this în cadrul callback-ului. Așadar:

imageRef.on('state_changed', (snapshot) => {
  var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
  document.getElementById("percent").innerHTML = "Progresso:" + Math.floor(progress) + "%";   
  console.log('Upload is ' + progress + '% done');
  switch (snapshot.state) {
    case firebase.storage.TaskState.PAUSED:
      console.log('Upload is paused');
      break;
    case firebase.storage.TaskState.RUNNING:
      console.log('Upload is running');
      break;
  }
},(error) => {
  // Handle unsuccessful uploads
}, () => {
  // Handle successful uploads on complete
  console.log('Uploaded');
  this.navCtrl.push(WelcomePage);
});