Ingo
Ingo

Reputation: 13

Nativescript Observable Object in Object UI not updating

i'm very new to nativescript and have a problem/question regarding an observable object in an observable object.

I have an App with a sidedrawer. Every page gets its binding context from the drawer page via its navigationContext. I need some of the data stored there in the pages. So the bindingContext of every page looks something like this...

const viewModel = observableModule.fromObjectRecursive({
    local_var1: "something as string",
    local_var2: true,
    globaldata: { global_var1: "global string",  global_var2: true }
});

In my xml file I can bind to globaldata.global_var2 without any problem. I use that for making some parts visible or collapse it. When the content of globaldata.global_var2 changes, the UI is not updated. I tried setting the variable with .set("var", true) and also directly. But the UI is not changing. For testing, I tried using local_var2 and that way, the UI is updating.

I also created a very little playground....

https://play.nativescript.org/?template=play-js&id=9dn3Yk&v=10

Can someone explain to me, why changes to an observable object inside an observable object is not reflected in the UI?

Thanks in advance and best regards ingo

Upvotes: 1

Views: 473

Answers (1)

Jesse Crossen
Jesse Crossen

Reputation: 6995

I'm seeing two problems in your playground, and fixing both seems to make it work as intended. First, this code in home-view-model.js needs to change:

var viewModel = observableModule.fromObjectRecursive({
  test: { boolShow = false }
});

That should be boolShow: false, or at least that runs successfully for me while the existing version doesn't.

With that out of the way, I notice both references to test.boolShow in homepage.xml use expressions:

visibility="{{ test.boolShow ? 'visible' : 'collapsed' }}"

and

text="{{ 'Touch me! ' + test.boolShow }}"

NativeScript listens for change events from the property being referred to, but for some reason it's unable to parse it from the expression, even though it knows enough to evaluate the expression. The workaround I've seen is to put the property key first, then a comma, then the expression, like so:

visibility="{{ test.boolShow, test.boolShow ? 'visible' : 'collapsed' }}"

and

text="{{ test.boolShow, 'Touch me! ' + test.boolShow }}"

If you do this, you should see the interface updating properly. I haven't yet seen any good documentation of the expression syntax, but the above kind of makes sense if you think about it as a use of the comma operator, which evaluates the left-hand side but only returns the right-hand side.

I'd love to see better documentation of this though, because I find the code for the binding system fairly hard to follow, and the examples I've seen only cover specific cases and leave many questions unanswered. For instance can/should we add multiple property values before the expression? If I refer to a.b.c, do a, b, and c all need to be observable or it would it work if just a and c were? It would be great to see more comprehensive documentation, since this feature is heavily used and has obvious consequences if it's used improperly.

Edit:

Looking at the docs again, my comments about the comma operator are off the mark, as the data binding actually accepts 1, 2, or 3 parameters. However, the documentation still doesn't seem to answer my open questions above.

Upvotes: 1

Related Questions