使用React-Native将文档提取为JSON

时间:2019-02-15 12:05:32

标签: arrays json react-native fetch document

我找到了一些类似的解决方案,但没有一个能完全满足我的要求。

这就是我想要做的:我在服务器中保存了一些文档以JSON格式保存,我想使用React-Native来获取这些文档并将其显示在手机上。 但是,当我不必每次将新文档上载到服务器时都不必更改代码时,请考虑一种解决方案。 React-native应该能够从服务器获取所有内容,甚至是新文档,而不必在 return {} 中添加新的代码行。这些文档可能彼此不同,有些仅包含文本,有些包含文本和输入字段,有些包含图片,文本和输入字段。

如果不清楚,请在评论部分让我知道。 任何建议将不胜感激!

JSON示例的样子:

    {  
   "results":[  
      {  

         "contract":{  
            "title":"Contract test",
            "content":"You can always follow the progress of your application by logging on the the application portal. Please note that all communication from DTU will take place via this portal. When we have sent you a message on the ..."
         },

        "fillable_fields": {
            "FIELD_NAME_1": "FIELD_VALUE_1",
            "FIELD_NAME_2": "FIELD_VALUE_2",
            "FIELD_NAME_N": "FIELD_VALUE_N"
        },
         "picture":{  
            "medium":"https://www.healthcaredenmark.dk/media/11272/bridgeit_logo.png"
         }
      }
   ]
}

我在React-Native中的代码:

class HomeScreen extends React.Component {

  constructor() {

    super();
    this.state = {};
    this.getRemoteData();

  }


  static navigationOptions = {
    title: 'List of documents',
  };



  getRemoteData = () => {
    const url = "https://demo8106568.mockable.io/results";
    fetch(url)
      .then(res => res.json())
      .then(res => {
        this.setState({
          data: res.results
        });
      })
      .catch(error => {
        console.log("get data error from:" + url + " error:" + error);
      });
  };


  capFirstLetter = (string) => {
    return string.charAt(0).toUpperCase() + string.slice(1);
  }


  renderNativeItem = (item) => {
    const contract =
      this.capFirstLetter(item.contract.title);
      //this.capFirstLetter(item.name.content);

    return <ListItem
            roundAvatar
            title={contract}
            subtitle={item.content}
            avatar={{ uri: item.picture.thumbnail }}
            onPress={() => this.onPressItem(item)}
          />;
  }


     onPressItem = (item) => {
     this.props.navigation.navigate('Detail', {item: item})
   }


  render() {
    return (
      <View>
        <FlatList
          data={this.state.data}
          renderItem={({item}) => this.renderNativeItem(item)}
        />
        {/* <Button
          title="Go Detail"
          onPress={() => this.props.navigation.navigate('Detail', {source: "homescreen"})}
        /> */}
      </View>
    );
  }
}





class DetailScreen extends React.Component {


  static navigationOptions = {
    title: 'Content of selected'
  };


  render() {

    const source = this.props.navigation.state.params.source;
    const item = this.props.navigation.state.params.item;
    let contract = "";
    let img = "";
    let inp = "";
    let content ="";

    if (item != null) {
      contract = item.contract.title;
      img = item.picture.medium;
      content = item.contract.content;
      inp = item.fillable_fields.FIELD_NAME_1;
    }


    return (

      <View style={styles.container}>

        <Text style={styles.text}>{contract} </Text>

        <Image
          style={{width: 300, height: 128}}
          source={{uri: img}}
        />

        <Text  style={styles.text} > {content} </Text>

        <TextInput style={{textAlign: 'center', borderWidth:1, marginBottom: 7, height: 50}} source={{uri: inp}}/>        

        <Button title="Go back to the list" onPress={this._goHome}/>

      </View>

    );
  }


  _goHome = async () => {
    this.props.navigation.navigate('Home');
  };
}

1 个答案:

答案 0 :(得分:0)

我了解您要完成的工作。但是我真的不认为您可以使它像您想要的那样工作。您可以将其与调用普通API端点进行比较。您很可能会采用类似的方法:

getContracts() {
    fetch('CONTRACTS_ENDPOINT').then(res => doSomethingWithContracts(res))
}

您已经知道此数据将返回合同,并且您已经知道在那里需要什么数据。因此,您可以轻松访问contract.namecontract.date之类的字段。

当您要呼叫其他端点时,您将执行类似的操作

getSomethingElse() {
    fetch('OTHER_ENPOINT').then(res => ...)
}

您将了解OTHER_ENPOINT随附的数据,因此您可以直接访问其字段。

所以我的建议是,将每个文档都视为一个单独的API端点。当然,如果更改文档,则还需要更改客户端实现,例如,如果将contract.title重命名为contract.otherWordForTitle,则显然也需要在客户端上进行更改。

根据我所知道的,要让客户始终知道文档结构而不进行更新以知道文档已更改,这是不可能的。但是,当然,我可能错了,可以采取一种解决方法:-)