无法在写入事务之外修改托管对象 - React Native,Realm

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无法在写入事务之外修改托管对象 - React Native,Realm相关的知识,希望对你有一定的参考价值。

onPressFavourites(item) {
    let realm = Realm.open({
    path: RNFS.DocumentDirectoryPath +'/trees.realm',
    schema: [sightingSchema, treeSchema],
    schemaVersion: 7,
   }).then(realm => {
    if(item.favourites === 0) {
     realm.write(() => {
        item.favourites = 1;
        item.favouritesColour = '#91b54d';
    });

    } else {
        realm.write(() => {
      item.favourites = 0;
        item.favouritesColour = 'transparent';
          }); 
    }
        }); 
    alert(item.favourites)// Update a property value
    }

我在点击按钮时尝试更新Realm中的对象,但是我收到了错误

“可能未处理的Promise拒绝(id:0):错误:无法修改写入事务之外的托管对象。”

这段代码几天前正在运行,但现在抛出了上述错误。

我仍然在学习React Native和Realm,但是根据我的理解和以下示例以及Realm文档,我使用了正确的代码,因此它应该可以工作。

编辑

似乎领域和写交易都很好。我们能够找到修复它的迂回方式,但是现在更新不会显示,直到应用程序刷新。

当使用参数Possible Unhandled Promise Rejection (id: 0): Error: Cannot modify managed objects outside of a write transaction.定义所选的Realm对象时,似乎产生了错误item。但是,如果我们创建一个与item相关的变量,它就不会产生该错误。有什么想法会发生这种情况吗?

onPressFavourites(item) {
    //console.log(realm);
    let realm = Realm.open({
        path: RNFS.DocumentDirectoryPath +'/trees.realm',
        schema: [sightingSchema, treeSchema],
        schemaVersion: 7,
    }).then(realm => {
        let trees = realm.objects('TreeInfo');
        for(var i=0; i<trees.length;i++){
            if(trees[i].commonName == item.commonName){
                var chosen = trees[i];
                break;
            }  
        }
        console.log(chosen);
        if(item.favourites === 0) {
                realm.write(() => {
                    //item.favourites = 1;
                    //item.favouritesColour = '#91b54d';
                    chosen.favourites = 1;
                    chosen.favouritesColour = '#91b54d';
                });
        }
        else {
            realm.write(() => {
                chosen.favourites = 0;
                chosen.favouritesColour = 'transparent';
            }); 
        }
    });
    alert(item.favourites)// Update a property value
}

编辑

render() { 
    var treeList = this.state.trees;
    console.log(treeList);
    const {navigate} = this.props.navigation;
     //var  tree = treeList[0];
    return(
        <Container>
            <Header searchBar style={styles.searchBar}>
              <Item style={styles.searchBarInner}>
                <Icon name="ios-search" />
                <Input placeholder="Search" />
              </Item>
            </Header>
            <List dataArray={treeList}
                renderRow={(item) => 
                    <ListItem style={styles.ListItem} button={true}>
                        <ListButton item={item}
                            onSelect={(item) => this.saveTreeInfo(item)}
                            onSelectFavourites={(item) =>                               this.onPressFavourites(item)
                            }
                        /> 
                    </ListItem>
                }
            >
            </List>
        </Container>
    );
}

以上是item传递给onPressFavourites函数的地方。 item是从一系列领域对象treelist生成并显示在列表中。

treelist数组来自变量this.state.trees,如下所示。

filterContent(){
        Realm.open({
            path: RNFS.DocumentDirectoryPath +'/trees.realm',
            schema: [sightingSchema, treeSchema],
            schemaVersion: 7,
            }).then(realm => {
                let trees = realm.objects('TreeInfo');
                let length = trees.length;
                let treeRealm = trees.sorted('commonName');

                console.log(this.state.leafEdges);
                if (this.state.leafEdges === 'smooth') {
                    var smoothLeaf = treeRealm.filtered('leafEdges CONTAINS "Smooth"');
                    this.setState({trees:smoothLeaf});
                }
                if (this.state.leafEdges === 'toothed') {
                    var toothedLeaf = treeRealm.filtered('leafEdges CONTAINS "Toothed"');
                    this.setState({trees:toothedLeaf});
                }
                if (this.state.leafEdges === 'notsure') {
                    this.setState({trees:treeRealm});
                }
                else if (this.state.leafEdges === 'null') {
                    this.setState({trees:treeRealm});   
                }
            });
    }
答案

用英语回答:

trees有关于realm的东西,所以你无法改变它。只需像这样复制一个新数组:

let trees = realm.objects('TreeInfo');

var arr=[];
for (let i = 0;trees && i < trees .length; i++) {
  var item=trees[i];
  var item2={
    id: item.id,
     ....
  }
arr.push(item2);
}
另一答案

这个trees 里面关联了realm里的一些东西,所以不能改变,要重新复制一个数组,像这样

let trees = realm.objects('TreeInfo');

var arr=[];
for (let i = 0;trees && i < trees .length; i++) {
  var item=trees[i];
  var item2={
    id: item.id,
     ....
  }
arr.push(item2);
}

以上是关于无法在写入事务之外修改托管对象 - React Native,Realm的主要内容,如果未能解决你的问题,请参考以下文章

我可以在 IIS 之外托管 ASP.NET 网站吗?

如何在托管对象上下文之外使用核心数据对象?

托管对象上下文是事务日志?

托管对象之外的 NSManagedObject 子类作为普通对象

JPA 混淆(托管与非托管实体)

使用领域和结果 JSON