Open grofit opened 8 years ago
Are you sure there are observable objects within the array?
that is an interesting question and not as easy to answer as I would like.
I am going to say yes, but with some assumptions:
1) When a viewmodel is tracked (i.e ko.track(myModel);
) all elements in an array become observables
2) When an element is added to an array which is being tracked, this will create an observable behind the scenes
If those assumptions are wrong then this would probably be part of the problem.
The answer is that array items are not made observable, even when the deep
option is used.
:( thats a major show stopper for our use case then, is there a way to get this behaviour? the example above is trivial but in a more realistic use case we would have things like: (its in typescript btw)
class Item
{
public Name = "";
public Weight = "";
}
class Inventory
{
public Items: Array<Item>;
}
class Character
{
public Inventory: Inventory;
}
So when we track the character we would want it to automatically track the child objects so when we display all items and the details are changed, this would update the Item
entries, there is also the concerns of validation in the real world, but currently this post-processes the model and uses ko.getObservable
to walk the tree.
Anyway with the above use case in mind, would you say there is a way to achieve child observables without having to manually track at each level?
Just a quick bump on this, is there anything in the roadmap to automatically turn arrays into observable arrays etc?
If this is not on the cards at any point then that is fine, but it has become a blocker in my current project so I could do with knowing either way.
@grofit check out https://github.com/nathanboktae/knockout-es5-option4
Thanks, I had seen this one before but it appeared to do full object replacement from what the examples showed, rather than object augmentation, not that I have any strong feelings to either.
I would say though that current ko-es5 is unfortunately not a complete replacement for using normal knockout, so unless this is addressed (which I think someone is working on in #37) I guess the only option if you don't (like me) want any ko.*
calls in your models you would need to move over to the other one.
I'm now curious as to whether this plugin provide an actual benefit over 'normal' ko. I really like the cleaner code of es5, but it needs to be a complete solution. Thoughts?
@jvissers I agree that it should be a complete replacement solution for ko.observable/observableArray
types, but unfortunately it is not. I have had to stop using it although I much preferred having the cleaner models but as you cannot do much complex without array support I have had to drop it and just return to the normal observable route.
@grofit - thank you for replying. I've went back to the blogpost that announced this feature. http://blog.stevensanderson.com/2013/05/20/knockout-es5-a-plugin-to-simplify-your-syntax There it reads:
By design, ko.track does not recurse into child objects. I would encourage you to declare child objects as instances of some class of your own, with its constructor having its own ko.track call — this gives you far more control over how much of the object graph is walked.
I'm not sure - but this seems to suggest that it was a design decision to have the plugin operate as it does right now. See also this: [http://jsfiddle.net/2Epfp/25/]. Is my interpretation correct?
@SteveSanderson , @grofit --- I've just watched a presentation of Steve where he actually uses this ES5 plugin (https://www.youtube.com/watch?v=MNiUcuo3Wio). This seems to suggest that the plugin is production quality and it works as designed.
Would be nice to hear if there are any real caveats here. Thanks.
The behavior is by design as the code documentation tells us:
// By design, this does not recursively walk child object properties, // because making literally everything everywhere independently observable is usually // unhelpful. When you do want to track child object properties independently, // define your own class for those child objects and put a separate ko.track call // into its constructor --- this gives you far more control.
sure but this approach makes one of the key reasons for using knockout es5 moot, as the general use case for knockout-es5 is so that your models are not dependent on knockout and have no knowledge of it. The moment you introduce ko.track(this);
into the constructor you may as well have just used basic knockout.
I do agree to some degree that you may not want to assume that by default everything nested wants to be observed, but at the same time you cannot assume that it doesnt want to be, as there is an option which already exists (deep
or something) it would make sense if this is set then it should trawl the entire tree.
So for normal objects you would do something like
ko.getObservable(myModel, myPropertyName);
and that works great, however lets assume I have a model like so:I have tried the following:
So is there some other way I am meant to get access to the observable objects within the array?