将OData结果映射到组件

时间:2018-08-29 17:58:49

标签: reactjs react-native odata

我试图用OData服务的结果完成列表的填充,我在项目中添加了以下Rest库:https://github.com/javorosas/react-native-rest-client

我这样创建了客户端类:

const svg = select('svg');


const width = +svg.attr("width");
const height = +svg.attr("height");

var div = select("body").append("div")
  .attr("class", "tooltip")
  .style("opacity", 0);


var g = svg.append("g")
  .attr('width', width)
  .attr('height', height)

svg.append("rect")
  .attr("width", width)
  .attr("height", height)
  .style("fill", "none")
  .style("pointer-events", "all")
  .call(zoom()
    .scaleExtent([1 / 2, 10])
    .on("zoom", zoomed));

function zoomed() {
  g.attr("transform", event.transform);
}

const simulation = forceSimulation(nodes)
  .force("link", forceLink(links).id(d => d.id))
  .force("charge", forceManyBody())
  .force("center", forceCenter(width / 2, height / 2))
  .on("tick", ticked);


const focus = svg.append("g")
  .attr("class", "focus")
  .style("display", "none");

const link = g.append("g")
  .attr("stroke", "#999")
  .attr("stroke-opacity", 0.6)
  .selectAll("line")
  .data(links)
  .enter().append("line")
  .attr("stroke-width", d => Math.sqrt(d.value));

const node = g.append("g")
  .attr("stroke", "#fff")
  .attr("stroke-width", 1.5)
  .selectAll("circle")
  .data(nodes)
  .enter()
  .append("circle")
  .attr("r", 5)
  .attr("fill", (d) => d.group === 1 ? '#ff0000' : '#0000ff')
  .call(drag(simulation))

  function ticked() {
    link
      .attr("x1", d => d.source.x)
      .attr("y1", d => d.source.y)
      .attr("x2", d => d.target.x)
      .attr("y2", d => d.target.y);

    node
      .attr("cx", d => d.x)
      .attr("cy", d => d.y);
  }

效果很好,现在我在实际屏幕上添加了一个按钮并处理了它的onPress事件。

 import RestClient from 'react-native-rest-client';

    export default class ServiceOrdersOData extends RestClient {
      constructor () {
           super('https://my000000.sapbydesign.com/sap/byd/odata/analytics/ds/Crmsoscb.svc', {
      headers: {

        Authorization: 'Basic X1NFSURPUjpJbmljaW8wMQ=='

      },
    });
  }
       getServiceOrdersOData () {
        // Send the url query as an object
        return this.GET('/Crmsoscb');

       }

    };

如果检查控制台,则可以看到odataValues从OData服务返回了所有记录,如果在浏览器中执行,则其格式如下:

CallOData(){

        const api = new ServiceOrdersOData();
        const odataValues = api.getServiceOrdersOData();
        console.log(odataValues);
    }

我现在要做的是在屏幕上用这些记录填充一个列表,比如说T_DocName和C_DocId。

我知道一个叫做map的函数,但是我不知道在这种特殊情况下如何使用它。

预先感谢您的帮助!

编辑:

所以我尝试了一些建议,但是当我尝试获取odataValues.d.results时,出现以下错误:{ "d": { "results": [ { "__metadata": { "uri": "https://my000000.sapbydesign.com/sap/byd/odata/analytics/ds/Crmsoscb.svc/Crmsoscb('.7~0000000000011DDFBEA73CE3794B5D1A')", "type": "CrmsoscbSvc.CrmsoscbType" }, "ID": ".7~0000000000011DDFBEA73CE3794B5D1A", "C_DbaServiceOrg": "00000000-0001-1DDF-B9FF-7D69E6266BF2", "C_DicIncCataId": "0000000000000000010010000", "C_DicIncCatId": "0000000000000000010014172", "C_DocId": "00000000000000000000000000000000001", "C_DocPostDate": "/Date(1290729600000)/", "C_DocSAgCorLc": "3", "C_DocUuid": "00000000-0001-1DDF-BEA7-3CE3794B5D1A", "C_DpyBuyerCntry": "US", "C_DpyBuyerPoscd": "14204", "C_DpyBuyerPty": "00000000-0001-1DDF-BA84-90748A78DCE3", "C_DpyBuyerRegn": "NY", "C_DpyBuyAbc": "A", "C_DpyBuyCity": "Buffalo", "C_DpyBuyInds": "42", "C_DpyBuyIndscsy": "0005", "C_DpyBuyNieid": "", "C_DpyProcPty": "00000000-0001-1DEF-BAD7-B58B002BEC36", "C_DpySalesUnit": "00000000-0001-1DDF-B9FF-7D69E6266BF2", "C_DpySrvsupTeam": "00000000-0001-1DDF-B9FF-7D69E6266BF2", "C_DpySrvExTeam": "00000000-0001-1DDF-B9FF-7D69E6266BF2", "C_DpySrvPerform": "00000000-0001-1DEF-BAD7-B5BC90EE6C36", "C_DroMatProcCat": "00000000-0001-1DEF-BA9F-2DABDB415385", "C_DroMatProdTy": "1", "C_DroRefoIndmat": "00000000-0001-1DEF-BAEB-6DD8248A2BA6", "C_DroRefoMat": "00000000-0001-1DEF-BAEA-3DA13AD047A6", "C_DsrProcCataid": "0000000000000000010010000", "C_DsrProcCatid": "0000000000000000010014000", "C_DsrSrvPrior": "3", "C_DsrWarranty": null, "C_DttInitMonth": "--11", "C_DttInitQuartr": "--Q4", "C_DttInitRecDt": "/Date(1290729600000)/", "C_DttInitWeekdy": "5", "C_DttInitYear": "2010", "C_DttInitYrmon": "2010-11", "C_DttInitYrquar": "2010-Q4", "C_DttInitYrweek": "2010-W47", "T_DocName": "Combi 75: Below average heat output", "NodeId": "0000000000011DDFBEA73CE3794B5D1A", "Count": 1 } ] } }

我认为这与以下事实有关:响应返回的不是集合,而是Promise吗?我要附上一个屏幕截图,其中显示了返回值的console.log本身:

Promise returned

您可以在其中看到一个奇怪的结构,而我的回复则包含在以下位置:

Cannot read property 'results' of undefined

有什么建议吗?

再次感谢!

2 个答案:

答案 0 :(得分:0)

因此,您具有这些odataValue,并且应该在收到它们时将其保存为状态。然后,在渲染中,您可以像这样渲染结果:

return (
   <View> {/* not necessary, this is only a mock of the rest of your layout */}
     {this.state.odataValues.d.results.map(result => <ResultRenderer result={result} />)}
   </View>
 )

ResultRenderer应该是呈现其收到的道具的组件。

我在这里展示了如何映射值,因为这就是您的要求。但是,更好的选择是使用FlatList,因为如果子列表很长,它将仅在屏幕上呈现子列表,从而节省了不必要的处理。您可以这样使用它:

<FlatList
  data={this.state.odataValues.d.results}
  renderItem={result => <ResultRenderer />}
/>

答案 1 :(得分:0)

[StartCaveat]

您需要查看地图的MDN:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map该网站提供了许多JavaScript信息,数量惊人!

[EndCaveat]

要使用map,必须首先确保所需的结果在数组内,您可以通过以下方式实现:

if(typeof(odataValues.d.results) != "undefined"){
}

现在我们知道我们可以访问该值了,并且它确实存在于我们可以使用map的作用域中!

  odataValues.d.results.map(item => {
    console.log("DocName", item.T_DocName);
    console.log("CDocId", item.C_DocId);
   });

以上内容将同时写入t_DocName和C_DocId的控制台。但是,我们需要在屏幕上获取此数据。

为此,我们可以执行以下操作:

<FlatList
 data={this.state.dataToDisplay}
 renderItem={({item}) => <Text>{`T_Doc: ${item.T_DocName} C_Doc ${item.C_DocId}`}</Text>}
/>

但是等等,我们需要创建dataToDisplay,状态是什么?

State是一个组件级别的全局容器,可以在您的类/函数内部的任何位置访问。

要创建dataToDisplay,请让我们编辑您的函数。

 CallOData(){
    const api = new ServiceOrdersOData();
    const odataValues = api.getServiceOrdersOData();
    if(typeof(odataValues.d.results) != "undefined"){
      this.setState({dataToDisplay: odataValues.d.results.map(item => {
        DocName: item.T_DocName,
        DocId: item.C_DocId
        });
      });
    }
}

太好了,我们有一个包含该值的状态,现在只需将平面列表添加到渲染中,检查数据即可完成!

render() {
        return (
          this.state.dataToDisplay && (<FlatList
            data={this.state.dataToDisplay}
            renderItem={({ item }) => <Text>{`T_Doc: ${item.DocName} C_Doc ${item.DocId}`}</Text>}
          />)
        )
      }

现在,您应该在屏幕上看到数据!是的