2017-10-21 42 views
1

J'ai la fonction suivante qui devrait cacher l'élément pour se connecter à Facebook si la connexion est réussie. Je crée deux fonctions, succès et erreur, qui se déclenchent après que Firebase se connecte correctement à l'utilisateur. Je sais que ces deux fonctions sont activées parce que j'ai été capable de les déboguer et de voir les instructions console.log à l'intérieur de la console après chaque déclenchement. Mais l'élément lorsque la connexion Facebook est réussie ne cache pas. Si je regarde les propriétés de this, alors isFacebookConnected et isGoogleConnected n'apparaissent pas mais les propriétés User et Providers le font.Comment mettre à jour le modèle asynchrone dans TypeScript?

Y a-t-il quelque chose que je ne comprends pas bien sur la façon de passer la référence de modèle actuelle à une fonction afin qu'elle puisse modifier l'état de l'interface utilisateur? Comment puis-je cacher l'élément de l'interface utilisateur en cas de succès?

FacebookAuthenticator.ts

import { firebase } from '../../app'; 
import { IAuthenticator } from './IAuthenticator'; 
import { Navigator } from '../navigation/Navigator'; 

export class FacebookAuthenticator implements IAuthenticator { 
    public successFunction: Function; 
    public errorFunction: Function; 

    constructor(success: Function, error: Function) { 
     this.successFunction = success; 
     this.errorFunction = error; 
    } 

    public authenticate() { 
     const successFunction = this.successFunction; 
     const errorFunction = this.errorFunction; 

     firebase.login({ 
      type: firebase.LoginType.FACEBOOK 
     }).then(
      function (result) { 
       successFunction(result); 
      }, 
      function (errorMessage) { 
       errorFunction(errorMessage); 
      } 
     ); 
    } 
} 

AccountViewModel.ts

export class AccountViewModel extends Observable { 
    public appVersion : string; 
    public User : User; 
    public isFacebookConnected : boolean; 
    public isGoogleConnected : boolean; 
    private authenticator : IAuthenticator; 
    private providers : Array<Provider>; 

    constructor() { 
     super(); 

     appVersion.getVersionName().then((result) => { 
      this.notifyPropertyChange("appVersion", "Version " + result); 
     }); 

     firebase.getCurrentUser().then((result) => { 
      this.User = result; 
      this.notifyPropertyChange("User", this.User); 
      this.providers = ProviderParser.getUserProviders(this.User); 
      this.setProviderConnectivty(); 
     }); 
    } 

    public setFacebookSwitch(togglingOn : boolean) { 
     const successFunction : Function = (model : AccountViewModel) => { 
      return() => { 
       model.isFacebookConnected = true; 
       model.notifyPropertyChange("isFacebookConnected", model.isFacebookConnected); 
      } 
     }; 

     const errorFunction : Function = (model : AccountViewModel) => { 
      return() => { 
       model.isFacebookConnected = false; 
       model.notifyPropertyChange("isFacebookConnected", model.isFacebookConnected); 
       dialogs.alert({ 
        title: "Unexpected Error", 
        message: "An unexpected error occurred during login. Please contact the developer.", 
        okButtonText: "Ok" 
       }); 
      } 
     }; 

     this.authenticator = new FacebookAuthenticator(successFunction(this), errorFunction(this)); 

     if (togglingOn && this.providers.indexOf(Provider.Facebook) === -1) { 
      this.authenticator.authenticate(); 
     } 
    } 
} 

Account.xml

<StackLayout row="2" column="0" class="preferenceGroup"> 
      <Label text="Connected Accounts" class="preferenceGroupHeading"/> 
      <GridLayout rows="*" columns="*, auto" visibility="{{ isFacebookConnected ? 'collapsed' : 'visible' }}"> 
       <Label row="0" column="0" text="Facebook" class="preferenceItem"/> 
       <Label row="0" column="0" 
         text="Repeat accesses your public profile, friend list, and email address" 
         textWrap="true" 
         horizontalAlignment="left" 
         class="preferenceSubText"/> 
       <Switch loaded="facebookSwitchLoaded" /> 
      </GridLayout> 
      <Label class="divider" /> 
      <GridLayout rows="*" columns="*, auto"> 
       <Label row="0" column="0" text="Google" class="preferenceItem"/> 
       <Label row="0" column="0" 
         text="Repeat accesses your public profile, friend list, and email address" 
         textWrap="true" 
         horizontalAlignment="left" 
         class="preferenceSubText"/> 
       <Switch checked="{{isGoogleConnected}}"/> 
      </GridLayout> 
     </StackLayout> 

Répondre

2

On dirait model ne référence pas le modèle réel que vous travaillez avec. L'objet actuel doit être this dans la fermeture.

Essayez de modifier votre code comme ceci et voir si cela fonctionne:

public setFacebookSwitch(togglingOn : boolean) { 
     const successFunction : Function = (model : AccountViewModel) => { 
      return() => { 
       this.isFacebookConnected = true; 

Si cela ne fonctionne pas (dans le cas où la fonction est prépondérant ce contexte), essayez de stocker this dans une température var premier:

public setFacebookSwitch(togglingOn : boolean) { 
     const myTempThis = this; 
     const successFunction : Function = (model : AccountViewModel) => { 
      return() => { 
       myTempThis.isFacebookConnected = true; 
+0

Merci. Le problème étant le contexte, la deuxième réponse a fonctionné; mais avec un peu de retard sur le côté de l'interface utilisateur. Cela voudrait dire que je n'ai pas vraiment besoin du paramètre (model: AccountViewModel) et que je devrais juste pouvoir l'appeler normalement. J'ai vraiment besoin de regarder plus dans les contextes car j'ai pensé en utilisant (model: AccountViewModel) et en appelant avec successFunction (this) je serais capable de conserver le contexte. Pourquoi ça ne marche pas comme ça? Avez-vous une ressource sur ce que je peux regarder? Je regardais cela aussi: https://github.com/Microsoft/TypeScript/wiki/%27this%27-in-TypeScript – uioporqwerty

+1

Heureux que cela a fonctionné. Cette connaissance vient plus de JavaScript que de TypeScript, je n'ai pas de ressource spécifique mais je recommanderais de googler quelque chose comme 'this in javascript tutorial'. Regardez aussi les fermetures (c'est pourquoi le 2ème exemple fonctionne). – Marc