GithubHelp home page GithubHelp logo

Comments (13)

martonx avatar martonx commented on July 19, 2024 3

I think if somebody need es5 compatiblity, then he should use 3.X instead of 4.

from tko.

davetropeano avatar davetropeano commented on July 19, 2024 1

It could work like knockout and the knockout-es5 plugin does today (and other frameworks do as well). By default, nothing in the POJO is observable. There is an API ko.track(obj) that takes a reference to an object or an array of property name strings.

With such an approach, the ko.observable() and ko.observableArray() functions are are unchanged from the user's perspective

from tko.

caseyWebb avatar caseyWebb commented on July 19, 2024 1

IE compat is the killer feature of Knockout. I'm sure I'm not alone in saying that dropping IE9 support is a deal-breaker. Dropping IE6-8, is one thing, but ES5 is still in use all over the place.

from tko.

brianmhunt avatar brianmhunt commented on July 19, 2024

Hi Dave - I was thinking either es5 type bindings - or the new "proxy" standard, which would be even better theoretically.

Mulling this - there are other issues that raise this, it's be nice to reference them here.

Cheers

from tko.

davetropeano avatar davetropeano commented on July 19, 2024

At first glance it does seem to make sense to implement something like track() with es6 proxies... +1

from tko.

davetropeano avatar davetropeano commented on July 19, 2024

Here's a nice article about implementing observables using es6 proxies:

Writing a JavaScript Framework - Data Binding with ES6 Proxies

from tko.

codymullins avatar codymullins commented on July 19, 2024

How would this work? Would all properties automatically be observable or only if they were bound/found in the UI?

from tko.

codymullins avatar codymullins commented on July 19, 2024

Additionally how would this work for backwards compatibility?

from tko.

abram27 avatar abram27 commented on July 19, 2024

It would be nice not to have to define the variable and again pass it to track when not making all the properties in the view model observable. I view the way in which observables are initialized and accessed as two different issues even though they are related. Something like this may work well:

ko.addObservables(this, 
     {
            loggedIn: false,
            userName: null,
            othersLoggedIn: []
     });

I guess this could happen currently with the function mapping.fromJS result passed into a merge function with this. It should potentially be a global setting to automatically get/set an observable vs using parentheses.

from tko.

ryansolid avatar ryansolid commented on July 19, 2024

I think this is a tricky thing. I've spent a lot of time coming with patterns around using Proxies and Getters/Setters around observable properties and even toyed with using TC-39 Observable Streams. And after all of that I have come to appreciate the simplicity of Knockout's Observables. I think there are good patterns and solutions in that space but I'm not sure they are Knockout.

Approaching this from the Getter/Setter and Proxy side of things you are desiring basically a plain object that provides a very simple interface to track dependencies. The gotcha is that in this case the thing that is observable is the objects properties, not the item itself. In so while the object here can be considered the view model, the getter is always returning the value so you have to either use a helper function, property accessor, or secondary getter to get the observable.

vm.counter; // the value - ex 5
obsv(vm, 'counter'); // ko.observable via helper
vm.get('counter') ; // ko.observable via accessor
vm.counter$ // ko.observable via secondary getter ie.. $ appended gets the observable

Proxies are interesting since they bring nesting to the table which is arguably the biggest pain in knockout in the sense that if you want deep data to be observable you have to map it. Even more interesting is you only have to map it at first request time so if nothing depends on a certain property you don't even need to wrap it in an observable.

Each nested level is still a proxy itself so it can be passed around, generate children proxies and nested into other proxies. But the object becomes the thing. If you wish to pass around single values or computeds they end up having to belong to a parent object or having a completely different syntax. I've found that acceptable but it is a consideration when you just want to pass a counter between components or view models. Not to mention taking data and mapping it in specific ways for certain uses is a bit stranger since the mapping to observable is happening automatically. It actually takes some thought to figure out what has really changed when you are mapping nested structures between different view models/components and should you have a Computed that returns an object should that object be coming back wrapped up as a nested Proxy object.

Knockout Observables are very different than TC-39 Observables and intentionally so. I'm pretty sure RX was already floating around in the early days of KO and Steve made some really key decisions. The fact they carry their values with them is huge. I tried to make a KO view data-binding library using RX Subjects and quickly realized that once you get to transforming the data you lose the ability to find the latest value outside of the pipe made it really awkward to setup things like computeds. As assuming you don't need computeds with Observables because you have all the operators to merge all your pure streams the amount of overhead to reduce every binding to a single value was insane. While the operators provided very clear code in my View Models the second I changed focus to my view code all my gains were squashed. If you have to make new variables for every combination of variables explicitly you are losing a lot of the gains of Knockout. Not to mention 2 way binding is interesting challenge because every chain needs to start and end with a Subject.

So the next idea was reducing the interopt so I'd end every TC-39 Observable with a toKO that would give me a computed, but the syntax wasn't worth the effort. Transforming from KO and back again was too verbose. I actually ended up working on porting my favorite operators and a couple custom operators for arrays in pure knockout. In essence I treated knockout arrays as single values instead of streams and the rest worked the same (map, filter, scan, flatMap). In so today I have a decent amount of knockout code that looks like:

users = ko.observableArray()
minmumAge = ko.observable(18)
mappedUsers = users.arrayMap(user=>{
    return {
        firstName: ko.observable(user.firstName)
        age: ko.obserable(user.age)
    }
}).map(list => {
    return list.filter(user => user.age() >= minimumAge())
})

So this leaves me with 2 different situations. One place where I'm embracing POJO looking proxies and another where I'm embracing functional transformations. One wants to mostly ignore KO Observables exist under the hood and the other is constantly using them directly. I think there is probably a way to reconcile both sides but moving further in either direction makes it more difficult for the other mentality I think.

from tko.

caseyWebb avatar caseyWebb commented on July 19, 2024

I want to chime in before anyone puts work into a Proxy implementation that Proxies can not be polyfilled or transpiled. I believe that alone is enough to rule out their usage in KO.

I'd also like to throw out knockout-decorators, because I think it scratches the itch of using POJOs, while remaining explicit about it.

from tko.

brianmhunt avatar brianmhunt commented on July 19, 2024

Knockout proper should be es3 compt through at least version 4 and 5.

TKO on the other hand may need Es6; you can see ko.proxy built into master, now, for beta 1. (Check out the .md in tko.conputed/docs)

from tko.

brianmhunt avatar brianmhunt commented on July 19, 2024

Closing this as ko.proxy is now in tko, and will be exposed for beta-1

from tko.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.