React-native:将场景绑定到 NavigationBar
React-native: Binding scene to NavigationBar
我正在组装这个 Ask/Answer 应用程序,遇到了这个障碍:
我想从导航栏触发场景中的功能。类似于登录应用程序,我在 NavigationBar 中有一个按钮来提交答案:
RightButton(route, navigator, index, navState) {
if (route.name=='TextInputView'){
return <TouchableHighlight
underlayColor="transparent"
style={{ marginRight:13, marginTop:0}}
onPress={() => this.refs.TextInputView.submitSolution()}>
<Text style={ styles.leftNavButtonText }>Done</Text>
</TouchableHighlight>
}
渲染场景(路线,导航器)看起来像这样:
if (route.name == 'TextInputView'){
return <TextInputView ref="TextInputView" navigator={navigator} {...route.passProps}/>
}
当然在 "TextInputView" 组件中我有一个 "submitSolution" 函数...
问题是如果我在现场并按下 "Done" - 我总是得到:
“undefined 不是一个对象(评估'_this2.refs.TextInputView')
一如既往:感谢您的帮助
好吧,您可以通过在场景本身中保留与提交相关的所有内容来做到这一点。
如何?
您可以通过在导航栏中插入一个按钮来实现 on-demand。
这是我为我正在处理的项目创建的解决方案:
https://rnplay.org/apps/dS31zw
我们的想法是为导航栏路线提供一个 object,它有一个标签和一个功能(以及任何你喜欢的东西......例如图标。)
作为奖励,您也可以插入标题!
注意:此技巧取决于在 NavigationBarRouteMapper 起作用之前调用 componentWillMount()。日后若有此变,必将破之。但它现在可以完美运行了!
'use strict';
import React, {Component} from 'react';
import ReactNative from 'react-native';
const {
AppRegistry,
StyleSheet,
Text,
View,
Navigator,
Alert,
TouchableHighlight
} = ReactNative;
class Home extends Component {
//This trick depends on that componentWillMount fires before the navbar is created
componentWillMount() {
this.props.route.navbarTitle = "Home";
this.props.route.rightNavButton = {
text: "Button",
onPress: this._doSomething.bind(this)
};
}
_doSomething() {
Alert.alert(
'Awesome, eh?',
null,
[
{text: 'Indeed'},
]
)
}
render() {
return (
<View style={styles.container}>
<Text>You are home</Text>
</View>
);
}
}
class AppContainer extends Component {
renderScene(route, navigator) {
switch(route.name) {
case "Home":
//You must pass route as a prop for this trick to work properly
return <Home route={route} navigator={navigator} {...route.passProps} />
default:
return (
<Text route={route}
style={styles.container}>
Your route name is probably incorrect {JSON.stringify(route)}
</Text>
);
}
}
render() {
return (
<Navigator
navigationBar={
<Navigator.NavigationBar
style={ styles.navbar }
routeMapper={ NavigationBarRouteMapper } />
}
initialRoute={{ name: 'Home' }}
renderScene={ this.renderScene }
/>
);
}
}
//Nothing fancy here, except for checking for injected buttons.
var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, navState) {
if(route.leftNavButton) {
return (
<TouchableHighlight
style={styles.leftNavButton}
underlayColor="transparent"
onPress={route.leftNavButton.onPress}>
<Text style={styles.navbarButtonText}>{route.leftNavButton.text}</Text>
</TouchableHighlight>
);
}
else if(route.enableBackButton) {
return (
<TouchableHighlight
style={styles.leftNavButton}
underlayColor="transparent"
onPress={() => navigator.pop() }>
<Text style={styles.navbarButtonText}>Back</Text>
</TouchableHighlight>
);
}
},
RightButton(route, navigator, index, navState) {
if(route.rightNavButton) {
return (
<TouchableHighlight
style={styles.rightNavButton}
underlayColor="transparent"
onPress={route.rightNavButton.onPress}>
<Text style={styles.navbarButtonText}>{route.rightNavButton.text}</Text>
</TouchableHighlight>
);
}
},
Title(route, navigator, index, navState) {
return (<Text style={styles.navbarTitle}>{route.navbarTitle || route.name}</Text>);
}
};
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
marginTop: 66
},
navbar: {
backgroundColor: '#ffffff',
},
navbarTitle: {
marginVertical: 10,
fontSize: 17
},
leftNavButton: {
marginVertical: 10,
paddingLeft: 8,
},
rightNavButton: {
marginVertical: 10,
paddingRight: 8,
},
navbarButtonText: {
fontSize: 17,
color: "#007AFF"
}
});
AppRegistry.registerComponent('AppContainer', () => AppContainer);
我正在组装这个 Ask/Answer 应用程序,遇到了这个障碍:
我想从导航栏触发场景中的功能。类似于登录应用程序,我在 NavigationBar 中有一个按钮来提交答案:
RightButton(route, navigator, index, navState) {
if (route.name=='TextInputView'){
return <TouchableHighlight
underlayColor="transparent"
style={{ marginRight:13, marginTop:0}}
onPress={() => this.refs.TextInputView.submitSolution()}>
<Text style={ styles.leftNavButtonText }>Done</Text>
</TouchableHighlight>
}
渲染场景(路线,导航器)看起来像这样:
if (route.name == 'TextInputView'){
return <TextInputView ref="TextInputView" navigator={navigator} {...route.passProps}/>
}
当然在 "TextInputView" 组件中我有一个 "submitSolution" 函数...
问题是如果我在现场并按下 "Done" - 我总是得到: “undefined 不是一个对象(评估'_this2.refs.TextInputView')
一如既往:感谢您的帮助
好吧,您可以通过在场景本身中保留与提交相关的所有内容来做到这一点。
如何?
您可以通过在导航栏中插入一个按钮来实现 on-demand。
这是我为我正在处理的项目创建的解决方案: https://rnplay.org/apps/dS31zw
我们的想法是为导航栏路线提供一个 object,它有一个标签和一个功能(以及任何你喜欢的东西......例如图标。)
作为奖励,您也可以插入标题!
注意:此技巧取决于在 NavigationBarRouteMapper 起作用之前调用 componentWillMount()。日后若有此变,必将破之。但它现在可以完美运行了!
'use strict';
import React, {Component} from 'react';
import ReactNative from 'react-native';
const {
AppRegistry,
StyleSheet,
Text,
View,
Navigator,
Alert,
TouchableHighlight
} = ReactNative;
class Home extends Component {
//This trick depends on that componentWillMount fires before the navbar is created
componentWillMount() {
this.props.route.navbarTitle = "Home";
this.props.route.rightNavButton = {
text: "Button",
onPress: this._doSomething.bind(this)
};
}
_doSomething() {
Alert.alert(
'Awesome, eh?',
null,
[
{text: 'Indeed'},
]
)
}
render() {
return (
<View style={styles.container}>
<Text>You are home</Text>
</View>
);
}
}
class AppContainer extends Component {
renderScene(route, navigator) {
switch(route.name) {
case "Home":
//You must pass route as a prop for this trick to work properly
return <Home route={route} navigator={navigator} {...route.passProps} />
default:
return (
<Text route={route}
style={styles.container}>
Your route name is probably incorrect {JSON.stringify(route)}
</Text>
);
}
}
render() {
return (
<Navigator
navigationBar={
<Navigator.NavigationBar
style={ styles.navbar }
routeMapper={ NavigationBarRouteMapper } />
}
initialRoute={{ name: 'Home' }}
renderScene={ this.renderScene }
/>
);
}
}
//Nothing fancy here, except for checking for injected buttons.
var NavigationBarRouteMapper = {
LeftButton(route, navigator, index, navState) {
if(route.leftNavButton) {
return (
<TouchableHighlight
style={styles.leftNavButton}
underlayColor="transparent"
onPress={route.leftNavButton.onPress}>
<Text style={styles.navbarButtonText}>{route.leftNavButton.text}</Text>
</TouchableHighlight>
);
}
else if(route.enableBackButton) {
return (
<TouchableHighlight
style={styles.leftNavButton}
underlayColor="transparent"
onPress={() => navigator.pop() }>
<Text style={styles.navbarButtonText}>Back</Text>
</TouchableHighlight>
);
}
},
RightButton(route, navigator, index, navState) {
if(route.rightNavButton) {
return (
<TouchableHighlight
style={styles.rightNavButton}
underlayColor="transparent"
onPress={route.rightNavButton.onPress}>
<Text style={styles.navbarButtonText}>{route.rightNavButton.text}</Text>
</TouchableHighlight>
);
}
},
Title(route, navigator, index, navState) {
return (<Text style={styles.navbarTitle}>{route.navbarTitle || route.name}</Text>);
}
};
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
marginTop: 66
},
navbar: {
backgroundColor: '#ffffff',
},
navbarTitle: {
marginVertical: 10,
fontSize: 17
},
leftNavButton: {
marginVertical: 10,
paddingLeft: 8,
},
rightNavButton: {
marginVertical: 10,
paddingRight: 8,
},
navbarButtonText: {
fontSize: 17,
color: "#007AFF"
}
});
AppRegistry.registerComponent('AppContainer', () => AppContainer);