我在xcode中的iOS应用程序有点问题.我有一个UITableView加载几百个单元格.当我向下滚动到特定单元格并向下钻取到详细视图控制器并再次返回时,主视图表一直返回到顶部.我看过以下两个相似的问题.
我仍然无法让这些工作.我不是最有经验的编码员,所以我真的很挣扎.
我知道像viewWillDisappear和viewDidAppear这样的东西需要改变,但我真的不能比这更进一步.
在此表中,我有一个reloadData功能,因此可以从服务器和工作搜索栏中下载最新数据.
无论如何,伸出援助之手会很棒.谢谢,
卢克
但是,没有一个答案/评论是令人满意的.它们要么告诉您克隆无法解决问题的数据,要么在ListView上设置唯一键来解决问题,但会创建一个新问题.
当您在ListView上设置唯一键并在删除后更新它时,整个视图再次呈现并滚动到顶部.向下滚动列表以删除项目的用户希望列表保持其位置.
这是一个人为的例子,使用我认为克隆数据的正确方法:
var ListViewExample = React.createClass({
getInitialState() {
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => {
r1 !== r2
}});
var rows = ['row 1', 'row 2', 'row 3'];
return {
dataSource: ds.cloneWithRows(rows),
};
},
_deleteRow() {
var rows = ['row 1', 'row 3'];
this.setState({dataSource: this.state.dataSource.cloneWithRows(rows)})
},
renderRow(rowData, sectionID, rowID) {
return <TouchableOpacity onPress={this._deleteRow}
style={{height: 60, flex: 1, borderBottomWidth: 1}}>
<Text>{rowData}</Text>
</TouchableOpacity>
},
render() {
return (
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
/> …
Run Code Online (Sandbox Code Playgroud) 我正在制作一个简单的反应本机应用程序,它有几个列表,它使用户有机会更新任何列表中的项目或将新项目添加到列表中.
但是,正如之前在StackOverflow上指出的那样,无法将项添加或推送到ListView,因为它应该是一个不可变的数据结构.即在此代码中,无法将新项目推送到数据源中
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
var data = ds.cloneWithRows(responseData)
var obj = {};
obj['someproperty'] = 'foo';
data.push(obj); //cannot push a new item into data
Run Code Online (Sandbox Code Playgroud)
所以我所做的就是保留this.state.items;
我从服务器获取的数据的副本(在下面的代码中)(我调用cloneWithRows
它),附加到该副本(如果是编辑则更新它),然后调用cloneWithRows
在任何时候有变化(通过编辑或创建新项目)并更新ui,然后更新服务器(最后一部分在反应原生应用程序范围之外)的变异副本上.所以总之,我有一个数据的副本,我可以变异以用作ds.cloneWithRows
我进行更改时的数据来源
但是,listForUI: ds.cloneWithRows(t)
如果我想要乐观地更新,保留数据结构的缓存似乎没有多大意义我可以改变它的唯一目的是将其用作不可变数据结构的源(在下面的代码中) UI(即在保存在服务器上之前显示更改).
替代方案(对我来说也没什么意义)似乎是更新服务器,并等待响应(不保留任何类型的缓存)任何时候我更新或添加新项目到我的列表,但这将慢吗?
问题:如果没有将数据的可变副本保存为缓存,是否有办法在反应原生中乐观地更新ui?
addNewItemToList: function(){
var t = this.state.items; //my cache of list items
var newListItem = {};
newListItem['id'] = 123;
t.push(newListItem); //adding-mutating the cache
//creating a new immutable ds
var ds = …
Run Code Online (Sandbox Code Playgroud) 我0.12.0
在Android上使用React Native()并在我的页面上有一个ListView组件.我希望能够从列表中删除项目.
这个ListView看起来像这样:
<ListView
dataSource={this.state.dataSource}
renderRow={this._renderStory}
onEndReached={this._getStories}
/>
Run Code Online (Sandbox Code Playgroud)
该rowHasChanged
方法看起来像这样.
this.state = {
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => {
return row1 !== row2;
},
}),
loaded: false,
};
Run Code Online (Sandbox Code Playgroud)
所有这一切都很好.
现在,要删除一个项目,我有这个代码:
var indexOfItem = this._data.findIndex((item) => item.id === story.id);
this._data.splice(indexOfItem, 1);
this.setState({
dataSource: this.state.dataSource.cloneWithRows(this._data),
});
Run Code Online (Sandbox Code Playgroud)
我可以确认该项目正在从中删除this._data
.this.state.dataSource._cachedRowCount
应该减少一个.正在更新状态并触发渲染周期.但该项目不会从页面中删除.更重要的是,如果我放入控制台登录this._renderStory()
,唯一发生的事情就是在列表底部呈现一个新行.
我错过了什么吗?我还需要做另一个步骤吗?
这里也提出了类似的问题,但他从来没有得到关于删除一行的答案.如何在ListView中添加/删除项目?
我在这个地方看到的所有其他例子都没有删除项目的例子.
更新:谢谢,它需要传递数组的克隆并设置一个键(抱歉只能接受一个答案).但这意味着整个清单正在呈现.最后,我只是在项目上设置了一个'removed'属性,测试了该属性的变化,如果一个项目被标记为remove,则在render方法中返回null,这比重新渲染所有项目更快.