2016-02-24 29 views
1

我使用Meteor和React作为我的应用程序。在我的应用程序中,我使用account-ui,account-facebook让用户可以使用facebook帐户登录。 现在,我想检查用户是否使用Facebook登录或定期用户/通过登录。我看着用户收集和发现在meteor-react render()方法中使用async meteor.call()

1) if user used facebook to login, there is services.facebook in user collection 
2) if user used regular user/pass to login, there is services.password in users collection 

在服务器,我有方法返回login服务(Facebook或密码)

Meteor.methods({ 
     getLoginService: function(){ 
      let services = Meteor.user().services; 
      if (typeof services.facebook!=='undefined'){ 
       return 'facebook'; 
      }else if (typeof services.password!=='undefined'){ 
       return 'password'; 
      } 
      return 'undefined'; 
     }, 
    }); 

在客户端,如果将检查,看看是否是(脸谱登录)或(用户/通过登录),然后我可以呈现相应的屏幕

App.Components.Dashboard = React.createClass({ 

    render() { 
    var lservice=''; 
    Meteor.call("getLoginService",function(error,service) { 
     if (error){ 
     }else { 
      lservice = service; 
     } 
    }); 

    if (lservice === 'facebook'){ 
     return (
      <div id="dashboard-content"> 
       <div className="row"> 
       <div className="col-lg-12"> 
        <h1 className="page-header">Facebook connect</h1> 
        <p>put facebook information here</p> 
       </div> 
       </div> 
      </div> 
     ); 



    }else{ 
     return (
      <div id="dashboard-content"> 
       <div className="row"> 
       <div className="col-lg-12"> 
        <h1 className="page-header">Facebook connect</h1> 
        <p>put facebook connect button here</p> 
       </div> 
       </div> 
      </div> 
     ); 
     } 

    } 
}); 

问题是在客户端。因为Meteor.call是异步的,所以lservice不会从回调函数中获取值。 我也试图找到一种方法将HTML返回到回调函数(错误,服务),但不成功。

无论如何,你是否知道解决这个问题。或者你有什么更好的主意来认识什么样的服务,用户用于登录(也许钩到帐户Facebook)

回答

2

开始移动您的电话Meteor.callcomponentWillMount,以便它只运行一次 - 就在组件之前第一次呈现。

你的render方法中的代码会在每次状态或道具改变时被调用,你可能只需要获得一次登录服务。

接下来,不是将service字符串存储在局部变量中,而是将其存储在state中,以便组件在每次更新时都会呈现它。

getInitialState() { 
    return {}; 
}, 
componentWillMount() { 
    Meteor.call("getLoginService", (error, service) => { 
    if(error) { 
     // handle error 
    } else { 
     this.setState({ service }); 
    } 
    }); 
}, 
render() { 
    const { service } = this.state; 

    if(service === 'facebook') { 
    // return facebook view 
    } else if(service === 'password') { 
    // return password view 
    } else { 
    // return loading view 
    } 
} 

的应用程序第一次呈现,该服务可能将无法使用(它会等着回来的要求),所以它会呈现else子句中的加载视图。

但是,当调用回调(提供没有错误)时,组件的状态将被更新,组件将重新呈现。

这次服务将可用,并显示正确的视图。

+0

谢谢丹太子。我将使用你的代码并看看。再次,非常感谢您的快速回答。 – David

+0

嗨,我试过了你的代码,并返回错误:Uncaught TypeError:无法读取null的属性'service'。如果我在const {service} = this.state之后放置alert(service),我可以看到服务的值是正确的,但错误仍然存​​在,并且页面无法呈现.. – David

+0

@David,您需要从'getInitialState'返回组件的初始状态,否则它将默认为'null',并且不能将'null'解构为对象。更新了答案。 –