问题
I am doing React Native project. This is my first project in React Native. And I am getting questions and answers in that (multiple questions and answers).
Each answer has multiple different styles with matching text of answer paragraph. If any matching text there, I have to apply those styles for that selected texts, There may be different font styles, underline, url link, emails.
I have tried with following code, but, It is displaying empty data.
text: the text to search for in the answer's text
instance: the instance to match in case of multiple instances found within the text (if zero is provided, match all instances)
link: this can be a url or a mailto to use for the matched text
styles: a collection of styles to be applied to the matching text
Json Response is following
{
"question": "How do I change my pwd?",
"answer": "To change your pwd, go to the Settings section from the main menu and choose the Change Password option. The new password will be your new password, as well. Still having difficulty logging in? Please contact the Services Team would be great.",
"format": [
{
"text": "Settings",
"instance": 1,
"link": "",
"styles": {
"fontWeight": "bold"
}
},
{
"text": "Change Password",
"instance": 1,
"link": "",
"styles": {
"fontWeight": "bold"
}
},
{
"text": "Services Team",
"instance": 1,
"link": "mailto:client@gmail.com",
"styles": {
"fontStyle": "underline",
"color": "blue"
}
}
]
}
There may be format key or may not be there. But, If that key there, I have to apply different styles for matching data for answer/question data. Even if there mail id, there, I have to show underline once tap on that, It should open email. If there any any url like website, It should open website on tap of it.
I am showing this data in Flatlist
export default class Cell extends PureComponent {
state = {
isSelected: false,
}
formatedContent = (format, label) => {
let managebleLabel = label; // initialize the working text
format.map((item) => {
const { styles, link, text } = item;
console.log('item', item);
const indexOfText = managebleLabel.indexOf(text); // Get the index of our text
const workingLabel = managebleLabel.substring(0, indexOfText + text.length); // Get complete working label with our text to format
managebleLabel = managebleLabel.split(text)[1]; // This is the left label we are going to work with next
const splittedLabel = workingLabel.split(text); // on position 0 we get the label with no format and on position 1 our text to format
const simpleLabel = <Text>{splittedLabel[0]}</Text>; // create the element
const formatedLabel = link && link.length > 0 ? (
this.isLink(text, link, styles)
) : (
<Text style={typeof styles === Object ? styles : {}}>{text}</Text>
); // Assign the format to label
return (
<Text>
{simpleLabel}
{formatedLabel}
</Text>
); // Join the labels
});
};
isLink = (label, link, style) => {
return (
<TouchableOpacity
onPress={() => Linking.openURL(link)}
style={typeof style === Object ? style : {}}
>
<Text>{label}</Text>
</TouchableOpacity>
);
}
onPress = () => {
const { index, onHeaderSelected, item } = this.props;
this.setState(prevState => ({
isSelected: !prevState.isSelected,
}));
}
render() {
const { isSelected } = this.state;
const { item } = this.props;
const answer = get(faqjson, 'answer');
const formatText = get(faqjson, 'format');
return (
<View style={styles.container}>
<TouchableWithoutFeedback onPress={this.onPress}>
<View style={styles.questionContainer}>
<Text style={styles.question}>{item.question}</Text>
<Image source={isSelected ? res.images.arrow_up : res.images.arrow_down} style={styles.image} />
</View>
</TouchableWithoutFeedback>
{isSelected && (
<View style={styles.answerContainer}>
<Text style={[styles.answer]} ellipsizeMode="tail">
{this.formatedContent(formatText, get(faqjson, 'answer'))}
</Text>
</View>
)
}
</View>
);
}
}
But, It is showing empty data after mapping. Any suggestions?
来源:https://stackoverflow.com/questions/58010417/how-to-apply-different-styles-dynamically-for-matching-text-from-a-dynamic-parag