将 Loader.active 设置为 false 不会立即释放项目 [英] Setting Loader.active to false doesn't release item immediately

查看:33
本文介绍了将 Loader.active 设置为 false 不会立即释放项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用例,根据属性值的存在或不存在,创建或删除引用它的对象.我正在使用 Loader 的目的,其中 active 属性绑定到属性,即当属性具有非空值时加载器被激活,当它被设置为 null 它被禁用.

I have a use case where depending on the presence or absence of a property value an object referencing it is either created or removed. I am using a Loader for the purpose, where the active property is bound to the property, that is when the property has a non-null value the loader is activated, when it is set to null it is deactivated.

但是问题是加载器不会立即释放它的项目,所以项目暂时引用了一个空属性,因此无法访问数据,而将属性设置为空会触发重新评估,从而导致swarm of 无法读取 null 的属性 x.

However the problem is that the loader doesn't release its item immediately, so for a moment the item references a null property, thus is unable to access data, while the setting of the property to null triggers reevaluations that result in a swarm of cannot read property x of null.

简单的逻辑表明这不应该发生.所以我认为问题可能是绑定评估的顺序错误,导致项目的绑定在加载器被停用之前被评估.所以我尝试删除 active 的绑定并手动设置它.然而问题仍然存在.

Simple logic suggest this should not happen. So I thought that maybe the problem is the order of binding evaluations is wrong, resulting in the item's bindings being evaluated before the loader is deactivated. So I tried removing the binding for active and setting it up manually. The problem however persisted.

所以这里有一个最小的表示来说明正在发生的事情:

So here is a minimal representation to illustrate what's going on:

Window {
  id: main
  visible: true
  width: 500
  height: 300

  property QtObject object : QtObject {
    property QtObject subObject: null
  }

  QtObject {
    id: subo
    property int i : 1
  }

  Loader {
    id: ld
    active: false
    sourceComponent: Text {
      text: object.subObject.i
      font.pointSize: 20
    }
  }

  MouseArea {
    anchors.fill: parent
    onClicked: {
      if (object.subObject) {
        ld.active = false
        object.subObject = null
      } else {
        object.subObject = subo
        ld.active = true
      }
    }
  }
}

请注意,在这种情况下,加载器在 属性设置为 null 之前被显式停用,但是,每次发生这种情况时,我都会在控制台:

Note that in this case the loader is explicitly deactivated before the property is set to null, yet nonetheless, every time that this happens I get a type error in the console:

qrc:/main.qml:25: TypeError: Cannot read property 'i' of null

这似乎不是正确的行为.所以也许是一个错误?还是我错过了什么?有关如何解决该限制的任何建议?请注意,在使用视图或中继器时会以某种方式避免这种情况.

This doesn't seem like correct behavior. So maybe a bug? Or am I missing something? Any suggestions on how to work around that limitation? Note that this is somehow avoided when using views or repeaters.

更新:为了进一步澄清,在我的实际生产代码中,如果不引用该属性,加载程序的项目就无法真正存在.所以这个想法是,该对象应该只在属性具有 null 以外的值时创建,并在它为 null 时销毁.

Update: To clarify further, in my actual production code the loader's item cannot really exist without referencing that property. So the idea was that the object should only be created when the property has a value other than null and be destroyed when it is null.

推荐答案

我昨天遇到了这个.我需要两个共享相同属性的装载机.在C++类中,我将两个Loader的active属性一一更新,也会导致这个问题.我的解决方案是使用 Binding 并进行如下设置:

I came across this yesterday. I need two Loaders which share the same property. In C++ class, I update the two Loader's active property one by one, which will also lead to that problem. My solution for this is using a Binding and do some setting like this:

Binding {
        target: contentItemAlias
        property: 'currentIndex'
        value: if (header.status == Loader.Ready) 
        header.item.currentIndex //ensure the current status is not null
        when: content.status === Loader.Ready // the content is ready
    }

实际上也许这对您没有帮助,但这是我的代码中的解决方案.我希望你能看到它并尝试一下binding.祝你成功.这是我的项目的链接:https://github.com/begoat/qmlLive

Actually maybe this will not help you, but this is the solution in my code. I hope you will see it and have a try at binding. Wish you success. here is the link to my project: https://github.com/begoat/qmlLive

这篇关于将 Loader.active 设置为 false 不会立即释放项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆