cannot changed the property of an object inside an array - data-binding

There is a parent element. One of its property is an array of objects. This array is initialised in the ready function. The display of this array is handed down to a child element. What I want to do is to update the quantity of each element in the array whenever the multiplier property changed. I tried to use the override dirty checking technique described in the docs but couldn't get it to work. I would appreciate some guidance.
[plunker link][1]
[1]: http://plnkr.co/edit/pCZyUC7YtgUU8cpejNpj?p=info

Here is working example: Plunk
Few things are corrected, one is this:
//DO not use 'this.setItems.0.quantity.value', but:
this.set('setItems.0.quantity.value', newQuantity);
console.log("New arr val: ");
console.log(this.setItems[0].quantity.value);
Docs:
https://www.polymer-project.org/1.0/docs/devguide/model-data
https://www.polymer-project.org/1.0/docs/devguide/data-binding#array-binding

Related

How do I dynamically remove an element from a QML basic type list?

I've successfully added elements using
list.push(element)
But how do I remove them? I've tried the following, but none of them seem to work.
list.pop()
list.pop_front()
list.remove()
list.remove(int)
list.remove(element)
For people who always keep ending up on this page, like I did: I found a very hacky solution to remove an element from a list<QtObject>.
myList = Array.from(myList).filter(r => r !== elementIWant2Remove)
This is not very elegant, but it does the trick, if you need to remove an element.
You can't remove individual items. According to the docs:
Note that objects cannot be individually added to or removed from the list once created; to modify the contents of a list, it must be reassigned to a new list.
This means that the pop method most likely won't exist with the basic list type. (However, there is a push method.)
You'll be much better off using JavaScript arrays.
property var myArray: [1, 2, 3]
Component.onCompleted: {
myArray.push(4);
myArray.push(5);
myArray.splice(1, 1) // simulates a remove
myArray.pop(); // pop last item
console.debug(myArray) // [1, 3, 4]
}
I've used ints here, but you can also store QML objects and other types as well. Using JavaScript arrays exposes your variables to most (if not all) of JavaScript's Array functions.

VueJS: Updating a parent object won't be reflected on child

I have a parent with an object data and I sent to the child part of it. I hope that when the parent is updated the child should be updated to.
groupProps is an object that every property has a lines array. In example: groupProps[1].lines[3] can exist.
<nova-grup v-for="group in m.groups"
:group="group"
:groupProp="groupProps[group.id]"
>
</nova-grup>
The first time it's working fine. The problem is when groupProps is changed the child isn't. For example, when changing or adding a line to groupProps.lines.
I have also noted that any computed variable based on the object isn't updating neither. Is this a limitation of vuejs? I'm using some lodash functions inside the computed variable
OK, it is a limitation.
https://v2.vuejs.org/v2/guide/reactivity.html#Change-Detection-Caveats
Finally I solved it doing this.myvar = Object.assign({}, this.myvar );

QML TableView access model properties from delegate

I have a TableView for which I've defined my own itemDelegate. Now, from within this delegate I can access the value for the column using styleData.value, but I'd also need to access the other properties in this same item but I can't find how to.
I need this, because the text styling needs to change depending on some other property of the item model.
Any ideas? thanks!
There is some documentation missing. Within the item delegate you can access the following (taken from the source code of TreeView.qml):
styleData (see documentation)
model (currently not documented)
modelData (currently not documented, not sure about this but I guess it's similar to ListView)
(By the way, what's also missing in the documentation but which is useful is styleData.role. Also, the documentation of the other delegates lacks some available properties too; the best is to peek into the source code of the QML file and have a look for the Loader element which instantiates your delegate. As a plus you learn how that creepy stuff works. ;))
With model and the row/column information you can then navigate to the item data. This code depends on the type of model.
If you're using QML's ListModel, then you can use model.get: model.get(styleData.row)[styleData.role] should then work (untested since I use it rarely, please give feedback).
If you're using a C++ QAbstractItemModel or friends, the best is to add a slot to the model class which takes just the row and role name, since that's the information the TableView works with (nor with role numbers nor with columns...).
However in both cases you shouldn't use the expression in a property binding! The notification system will not work since you don't use the property system for accessing the data. According to your question, I guess you wanted to use it in a expression with binding. I don't know how to properly listen to changes in the model manually.
An alternative approach is to access the other items of the row and provide a property there. Some hints:
From within one item, you can access other items of the same row by walking the object tree up twice (first to the Loader which instantiates your component, then to the actual row) and then down twice (first to the particular child object which is a Loader, then its instantiated item). You need to know the column number you want to access (not the role name), I assume you want to access the first column (index 0):
parent.parent.children[0].item
You can provide the model data using a property in each item. Assuming a simple Text element this might be:
Text {
property variant value: styleData.value // <-- Here you make it available
// your other stuff
}
Putting them together could look like the following. In this example I assume the first row contains an integer, and if it is zero, the second column should be red.
// (within TableView)
itemDelegate: Text {
property variant value: styleData.value
text: styleData.value
color: (styleData.column == 1 && parent.parent.children[0].item.value === 0)
"red" : "black"
}
I think it's pretty easy if you read the source code of TableViewItemDelegateLoader.qml (it is a private code in qtquickcontrol)
To access any role you use use : model[your_role_name] .
For exp: model["comment"]
Faced with same problem today, this is result of my investigations (Qt 5.2.x)
If you have hard limit to TableView, there is only one correct solution - use model.get(styleData.row)["roleForStyling"] as #leemes wrote. But it will very slow if you have big amount of data in model and using, for example, proxy model for sorting/filtering.
Direct solution from #leemes answer is great, but in general case not be working, because in TableView any Item wrapped in Loader and therefore independent from parent and other items:
When some item is created (where you want to change text style)
another element (from which to receive identity) cannot yet be
created
You may not have "parent" on item creation (i.e. binding will
be broken)
In my case, the best solution for deep customise was creation of the simple wrapper for ListView. In this case you have access for complete row data in delegate without the overhead. Highlights for making component ("My own ListView as table"):
Create standalone header (Rectangle or Item) - do not use header form ListView.This make it fixed for any amount of data.
Wrap ListView to ScrollView (if you need scrollbars)
Use Clip: true property in list for make correct
Set style for highlight and set highlightFollowsCurrentItem:true in ListView
As bonus in future this may be used for make "TreeTable" :)

Flex: select tree node right after the dataProvider is been assigned / updated / replace

i have a Flex tree control and im trying to select a tree node 3 levels down right after the dataProvider is assigned with a collection object like the following.
basically treeItem1, treeItem2, treeItem3 are the nodes in the tree and treeitem3 is a child of treeItem2 which is a child of treeItem1. Assume these treeItem(1,2,3) are referenced correctly from the collection items.
my problem is that if i wait for the whole component to load completely then select the nodes, it open/select/scrolltoIndex correctly. However, if i were to select the node right after the dataProvider is assigned, then it doesn't even open or select (basically the this.treeService.selectedItem is always null).
can anyone point out what i did wrong? is there anything needs to happen after the dataProvider is assigned?
thanks
this.treeService.dataProvider = oPricingHelper.getCurrentPricingSercicesTreeSource();
this.treeService.expandItem(treeItem1, true);
this.treeService.expandItem(treeItem2, true);
this.treeService.selectedItem = treeItem3;
this.treeService.scrollToIndex(this.treeService.selectedIndex);
I have used the updateComplete event to know when a component (such as a DataGroup or List) has completed rendering after performing a simple task (such as updating the dataProvider reference). Of course, you have to be careful and remove listening to updateComplete because it can run a lot, unless you have a need for it to run.
Something like:
//...some function...
this.treeService.addEventListener(FlexEvent.UPDATE_COMPLETE, onTreeUpdateComplete);
this.treeService.dataProvider = oPricingHelper.getCurrentPricingSercicesTreeSource();
//...rest of some function...
private function onTreeUpdateComplete(event:FlexEvent):void {
this.treeService.removeEventListener(FlexEvent.UPDATE_COMPLETE, onTreeUpdateComplete);
this.treeService.expandItem(treeItem1, true);
this.treeService.expandItem(treeItem2, true);
this.treeService.selectedItem = treeItem3;
this.treeService.scrollToIndex(this.treeService.selectedIndex);
}
I'm not positive your experiencing the same issue but I seem to have the same type of problem with using the advanced data grid, it appears in these cases where the dataprovider is acceptable as multiple types, the components do some extra work in the background to wrap things up into something Hierarchical (HierarchicalData or HierarchicalCollectionView) and in doing so the dataprovider setter call is not synchronous (so it will return before actually having assigned the internal property storing the dataprovider). I've used callLater in this case with moderate success, callLater is generally a bad practice but basically adds a function to a list of functions to call once background processing is done, so this is assuming that something in the dataprovider setter called UIComponent.suspendBackgroundProcessing() and that it will subsequently call UIComponent.resumeBackgroundProcessing() and then it will execute the list of functions added by using callLater. Alternatively you could use setTimeout(someFunction,1000).
These are both "hacks" the real solution is to dig into the framework code and see what it's really doing when you tell it to set the dataprovider. Wherever you see that it actually has set the dataprovider you could extend that class and dispatch an event that you could listen for to run the function to do the selections after this point.
If anyone has a better solution please by all means correct me (I would love to have a better answer than this)

Sorting QObject children

i noticed that QObject::children() method return a const reference to QObjectList, that contains the children of the qobject. Will it be safe to cast away the constness and sort the list with qSort?
Thanks
Anton
No, you should not do this. This is the definition of QObject::children():
inline const QObjectList &children() const { return d_ptr->children; }
This means you directly get the reference of the internal objectlist.
And the documentation says:
Note that the list order changes when
QWidget children are raised or
lowered. A widget that is raised
becomes the last object in the list,
and a widget that is lowered becomes
the first object in the list.
It looks like a bad idea to mess with this list.
Maybe. But why risk it? Can't you just copy the QObjectList and sort your local copy?

Resources