Извлечение документа в формате JSON с использованием React-Native - PullRequest
0 голосов
/ 15 февраля 2019

Я нашел несколько похожих решений, но не одно, которое делает именно то, что я хочу.

Вот что я хочу сделать: у меня есть несколько документов, сохраненных как 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 голосов
/ 15 февраля 2019

Я понимаю, что вы пытаетесь достичь.Но я действительно не думаю, что ты сможешь заставить это работать так, как ты хочешь.Вы можете сравнить это с вызовом нормальной конечной точки API.Скорее всего, у вас будет такой метод:

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

Вы уже знаете, что эти данные возвращают контракты, и вы уже знаете, какие данные ожидать.Поэтому вы можете легко получить доступ к таким полям, как contract.name или contract.date.

. И когда вы захотите вызвать другую конечную точку, вы сделаете что-то похожее

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

Вы будете знать данныеон поставляется с OTHER_ENPOINT, так что вы можете напрямую получить доступ к его полям.

Поэтому я предлагаю думать о каждом из ваших документов как об отдельной конечной точке API.Конечно, если вы измените свой документ, вам также потребуется изменить реализацию на стороне клиента, поэтому, например, если вы переименуете contract.title в contract.otherWordForTitle, то вам, очевидно, придется изменить это и на клиенте.

Из того, что я знаю, что вы хотите, чтобы клиент всегда знал структуру документа, не обновляя его, чтобы знать, что документ изменился, невозможно.Но, конечно, я могу ошибаться, и может быть обходной путь :-)

...