2017-10-21 83 views
1

我有以下功能,应该隐藏连接到Facebook的元素,如果连接成功。我创建了两个函数,成功和错误,在Firebase正确登录用户后触发。我知道这两个函数的命中,因为我已经能够调试它们并在每次触发后在控制台中查看console.log语句。但Facebook连接成功时的元素不会隐藏。如果我查看this的属性,则不会显示isFacebookConnectedisGoogleConnected,但UserProviders属性会显示。如何在TypeScript中更新模型异步?

有什么我误解了如何传递当前模型引用到一个函数,以便它可以修改UI的状态?我如何获得UI元素以隐藏成功?

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> 

回答

2

貌似model没有引用您正在使用的实际模型。关闭中的当前对象应该是this

尝试修改这样你的代码,看看它的工作原理:

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

如果不工作(当功能被重写此背景下),尝试存储this在一个临时VAR第一:

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

谢谢。问题在于上下文,所以你的第二个答案是有效的。尽管在UI方面有点延迟。这意味着我不需要(model:AccountViewModel)参数,我应该可以正常调用它。我真的需要更多地关注上下文,因为我认为通过使用(model:AccountViewModel)并使用successFunction(this)调用,我将能够保留上下文。为什么它不这样工作?你有这方面的资源我可以看看吗?我也在看这个:https://github.com/Microsoft/TypeScript/wiki/%27this%27-in-TypeScript – uioporqwerty

+1

它的工作很开心。这些知识来自JavaScript而不是TypeScript,我没有特定的资源,但会推荐使用类似'javascript教程'这样的东西。也看看关闭(这就是为什么第二个例子工作)。 – Marc