2015-06-28 11 views
5

Sto cercando di capire meglio this Firebase authenticator for Ember SimpleAuth:Cosa succede quando si associa "questo" a una funzione di Brace?

import Ember from 'ember'; 


export default Ember.Controller.extend({ 


actions: { 
    login: function() { 
     this.get('session').authenticate('authenticator:firebase', { 
      'email': this.get('email'), 
      'password': this.get('password') 
     }).then(function() { 
      this.transitionToRoute('index'); 
     }.bind(this)); 
    }, 
    logout: function() { 
     this.get('session').invalidate().then(function() { 
      this.transitionToRoute('login'); 
     }.bind(this)); 
    } 
} 
}); 

qualcuno dovrebbe spiegare che cosa ".bind (questo)" sta facendo e come esattamente si legano sta lavorando in questo caso particolare?

Edit: Dopo un po 'di riflessione e di ricerca, ecco la mia proposta di spiegazione di ciò che può accadere:

La sezione ".then" del codice non hanno accesso al contesto originale di 'questo'. ".bind (this)" imposta il valore di "this" (che in questo caso è l'oggetto controller corrente) su "this" all'interno della funzione ".then".

Ciò può essere dimostrato dal fatto che se la sezione ".bind (this)" viene rimossa, la sezione "transitionTo" del codice non funziona.

D'altra parte, se scriviamo il codice come segue, non abbiamo bisogno di usare ".bind (questo)":

import Ember from 'ember'; 


export default Ember.Controller.extend({ 


actions: { 
    login: function() { 
    var _this = this; 
     this.get('session').authenticate('authenticator:firebase', { 
      'email': this.get('email'), 
      'password': this.get('password') 
     }).then(function() { 
      _this.transitionToRoute('index'); 
     }); 
    }, 
    logout: function() { 
     var _this = this; 
     this.get('session').invalidate().then(function() { 
      _this.transitionToRoute('login'); 
     }); 
    } 
} 


}); 

Pensieri?

+0

Sì, dovresti aggiungere la parte inferiore del tuo post come risposta (è corretto rispondere alla tua stessa domanda). – steveax

risposta

9

Cosa succede quando si associa "questo" a una funzione di Brace?

Nell'esempio, .bind() non viene utilizzato nelle funzioni di colore scuro. Viene utilizzato sulle solite funzioni anonime (callback). Quindi, la tua domanda non ha nulla a che fare con Ember.

Con un callback intendo una funzione anonima passata come argomento anziché assegnata a una proprietà di un oggetto.

Tale funzione sarà associata a window, i. e. this all'interno della funzione restituirebbe window.

un approccio tradizionale di accedere al perimetro esterno sta assegnando this ad una variabile in un ambito esterno, quindi l'accesso alla variabile nel campo di applicazione interna:

var _this = this; 

someMethod(function() { 
    console.log(this); // => window 
    console.log(_this); // => Outer scope 
}); 

Questo approccio è buono quando è necessario accedere sia interiore e ambito esterno. Ma non c'è niente utile nel perimetro interno, così possiamo scrivere corta:

someMethod(function() { 
    console.log(this); // Outer scope 
}.bind(this)); 

Procedimento .bind() viene eseguito in ambito esterno sulla funzione anon. Lega la funzione allo scopo esterno. Pertanto, l'ambito interno della funzione sarà lo stesso dell'ambito esterno ed è possibile utilizzare come al solito this, come se l'ambito non fosse cambiato.

In CoffeeScript, è possibile utilizzare la freccia grasso per rimanere in ambito esterno:

_this = this 

someMethod -> 
    console.log this # winodw 
    console.log _this # Outer scope 
someMethod => 
    console.log this  # Outer scope 
    console.log ` this ` # You can still access window like ` this `, pun intended 

In ES6 è possibile utilizzare la freccia grasso troppo:

foo(() => { 
    console.log(this); 
}); 

Ricordate che se come in CoffeeScript la freccia grassa mantiene lo scopo esterno, significa una cosa diversa! In ES6 la freccia di grasso crea una funzione falsa che non è in grado di avere il proprio ambito.

Questo è importante perché alcune librerie comunicano con un callback applicando il callback a un determinato ambito e si aspettano di eseguire this.something() su di esso. Non funzionerà con la freccia di grasso ES6 (beh, potrebbe funzionare tecnicamente con Babel perché Babel converte le frecce fat ES6 in funzioni tradizionali, ma non dovresti fare affidamento su questo).

Per ulteriori informazioni su .bind(), vedere Function.prototype.bind() on MDN.

+0

spiegazione super-chiara. Grazie. – learningMachine

+0

ok. Ho accettato e votato. – learningMachine

3

Questo è esattamente ciò che sta accadendo. Se si .bind (questo), non è necessario creare un alias per questo al di fuori della funzione. Vedi this question per ulteriori spiegazioni.

Problemi correlati