2016-12-16 65 views
0

完全不同于React Native(和React)。在ListView中呈现静态图像

我:

export default class MyApp extends Component { 

    // Initialize the hardcoded data 
    constructor(props) { 
    super(props); 
    const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 
    this.state = { 
     dataSource: ds.cloneWithRows([ 
     'property1', 'property2', 'property3', 'property4' 
     ]) 
    }; 
    } 

    render() { 
    return (
     <View style={{flex: 1, paddingTop: 50}}> 
     <ListView 
      dataSource={this.state.dataSource} 
      renderRow={(rowData) => <Image style={styles.image} source={require('./images/' + {rowData} + '.jpg')} />} 
     /> 
     </View> 
    ); 
    } 
} 

我试图显示四个图像(存储在图像文件夹中的同一目录索引中)。我硬编码的图像名称(property1,property2等)。这是给我的错误未知命名模块:“./images/[object对象] .JPG”

在官方文档望着图像页面(https://facebook.github.io/react-native/docs/images.html)我想创建一个变量来存储首先完整路径,然后根据文档使用如下内容:<Image source={path} />

另外,建议为renderRow创建一个单独的函数吗?

+0

哪个装载机用于图像? – corvid

+0

对不起 - 不知道装载机是什么意思?我只是把它们放在本地目录 – tommyd456

+0

中,你用你的webpack中的babel-loader加载你的javascript。但是当你遇到一个'.jpg'时,你使用的是哪个loader? – corvid

回答

1

让我们回顾一下你的问题的不同方面:

  • 错误:Unknown named module: './images/[object Object].jpg'

你逝去的string数组你dataSource,因此中的rowData具有字符串值,您可以直接连接到'./images',但是,您正在混合Ja vaScript和JSX的“上下文”(缺少更好的术语)。当你这样做:

(rowData) => <Image style={styles.image} source={require('./images/' + {rowData} + '.jpg')}

无论你通过{}为道具的价值里面,如JavaScript进行评估,所以source={require('./images/' + {rowData} + '.jpg')}将是纯JavaScript。因此,当你将“rowData”包含在这个“上下文”中的大括号中时,你将它转换为一个对象,并且由于你正在使用新的ES6'快捷键'作为对象文字,所以你基本上做的是用一个键实例化一个对象rowData,其值为rowData。从本质上讲,你transpiler正在做这样的事情:

(rowData) => <Image style={styles.image} source={require('./images/' + {rowData: rowData} + '.jpg')}

的JavaScript尝试将对象转换为string,是当然[object Object]的默认表示。我会被替换为以下(注意,它仍然是错误的处理图像方面作出反应母语,我会为以后的解决方案。):

(rowData) => <Image style={styles.image} source={require('./images/' + rowData + '.jpg')}

甚至更​​好:

​​./images/${rowData}.jpg )}

你可以MDN阅读更多关于模板字符串。

现在,对于图像的问题,如docs中所述,必须静态地知道静态资产的名称(即'transpilation'时间),所以由字符串连接生成的动态名称无效。我认为这样做的理由是可以识别App中的所有资源,以便将它们打包在捆绑包中。

尽管如此,还是有一些简单的解决方法。你的情况,你可以做这样的事情:

const property1 = require('./images/property1.jpg'); 
const property2 = require('./images/property2.jpg'); 
const property3 = require('./images/property3.jpg'); 
const property4 = require('./images/property4.jpg'); 

const images = {property1, property2, property3, property4}; // ES6 literal objects. This basically means {property1: property1, property2: property2, ... 

// Now images are known statically 

export default class MyApp extends Component { 

    // Initialize the hardcoded data 
    constructor(props) { 
    super(props); 
    const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 
    this.state = { 
     dataSource: ds.cloneWithRows([ 
     'property1', 'property2', 'property3', 'property4' 
     ]) 
    }; 
    } 

    render() { 
    return (
     <View style={{flex: 1, paddingTop: 50}}> 
     <ListView 
      dataSource={this.state.dataSource} 
      renderRow={(rowData) => <Image style={styles.image} source={images[rowData]} />} 
     /> 
     </View> 
    ); 
    } 
} 

至于你的最后一个问题:我想说的是创建一个单独的函数只依赖于功能的“大小”:如果你只是在做一个简单的映射,就像你在发布的代码片段中做的那样,单独的函数不是可取的,因为代码更具可读性。但是如果你要做2-3行计算,可能建议将你的功能包含在外部函数中。

0

这个例子来自我自己的项目,它工作正常。

<Image style={styles.facebookImage} source={require('../statics/facebook-logo-white.png')}></Image> 

,你能做些什么来设置源dynamicalli是使用状态,就像这样:

<Image style={styles.facebookImage} source={require(this.state.imageRoute)}></Image> 

当然,你必须建立正确的状态组件是这样的:

this.setState({imageRoute: 'your rute here'}); 

如果我是你,我会使用一个单独的renderRow函数为了让代码更具可收缩性,请尝试如下所示:

_renderRow(rowData) { 
    return (
     <Image style={styles.facebookImage} source={require(this.state.imageRoute)}></Image> 
    ); 
    } 

并且不要忘了,包括从反应本地图片是这样的:

import { 
    ... 
    Image 
} from 'react-native'; 

希望它可以帮助你。

0

基本上你不能用React Native做到这一点。您可能需要将它们放在文件的顶部,并将它们作为变量而不是动态路径使用。继承人从他们的开发团队报价:

We intentionally don't support dynamically generated image names because it makes it very hard to manage assets over time, just like how you wouldn't want to do var MyComponent = require('./' + libName + typeOfComponent); or something like that. Dynamic image name generation like this also won't work with the new dynamic asset managing system we're rolling out which let's you add and update assets on the fly with just cmd+R (no more need to add to Xcode and recompile).