Giter Site home page Giter Site logo

knockout / tko Goto Github PK

View Code? Open in Web Editor NEW
271.0 271.0 31.0 9.29 MB

๐ŸฅŠ Technical Knockout โ€“ The Monorepo for Knockout.js (4.0+)

Home Page: http://www.tko.io

License: Other

JavaScript 36.32% HTML 0.01% CSS 0.19% Makefile 0.25% TypeScript 63.17% Pug 0.06%
framework frontend frontend-app frontend-framework frontend-web knockout mvvm mvvm-framework tko

tko's People

Contributors

4ver avatar adamwillden avatar alundiak avatar bcdanieldickison avatar brianmhunt avatar caseywebb avatar cervengoc avatar codymullins avatar danieldickison avatar dependabot[bot] avatar krnlde avatar lkarthee avatar mattbarkerdev avatar mbest avatar rampion avatar wader avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tko's Issues

components) Support JSX templates

(From tko.components/issues/5, pre monorepo)
Re: knockout/knockout#1663

Proposal:

Add jsx as an option to the template registration e.g.

ko.components.register('test-widget', {
   viewModel: SomeTestWidgetViewModelClass,
   template: {
     jsx: /* JSX Things ...*/
   }
})

@daedalus28

Just a note about this - part of the advantage of JSX is the ability to use native js things instead of having custom DSLs (for example, using a simple array.map instead of learning bindings like foreach). For this to really shine, bindings themselves should also be able to be called as functions and ideally be able to be less KO specific. The ideal situation here is probably to internally allow using a template that is a function which becomes a computed so you can do all the things you'd do in react like map, etc and not have to have it map to some custom binding. React + MobX is a great example of this


@Tschaul

Thats how i see it too. The knockout bindings would be gone / not needed anymore.

But knockout would have to do slightly more than handle the jsx template as computed observable. It has to instantiate other ko-Components that are used inside the template and handle their lifecylce. But that shouldn't be too different than what knockout is doing with the current templating logic.

I have a working proof of concept using the virtual-dom library here: https://github.com/Tschaul/hyperknock/blob/master/index.jsx

template binding's afterRender handler does not get invoked on DOM render

I am trying out TKO 4.0 in ES6 semantics with transpilation done using Babel.

When I use template binding and pass a class method to afterRender, the method does get invoked but the reference of this becomes window Object. However, if the same class method is added to click binding, method gets invoked and there this reference points out to class or the viewmodel.

Not sure if this is an issue with TKO 4.0 or ES6 compilations. If someone can help me on this with a sample working example of afterRender using ES6 and TKO 4.0 would be of great help at this time. As we have planned for migration from KO to TKO for good performance reason.

I am attaching my tried code zipped below:

Thanks is advance.

side-bar.zip

Fix backwards ES3/6/IE9 compat + polyfills

To be backwards compatible the TKO library needs to be polyfilled. Examples of ES6 features that need polyfill:

  • Generators
  • Object.entries/Object.assign
  • Backticks
  • => functions
  • Spreads

Here are some things needed to polyfill:

  • WeakMap (?)
  • Object.assign / entries
  • Promise
  • Generators
  • Map + Set
  • Node.remove
  • Symbol, Symbol.interator / observable
  • String::startsWith

Everything in TKO should be polyfillable (i.e. no WeakSet), but my attempts to make it work, using the config below (among many variants), never worked quite right.

An example of the Babel attempt, removed in 7dbec4c, is:

Support for {{#else}} ?

I might be misinterpreting the release notes but I cannot get {{#else}} to work and assumed (lol) that since the virtual binding for else was added a punches-like equivalent would come for "free"

Here's the broken example:

JSBin

Using the {{#if}} / {{#ifnot}} works. I tried an {{#else}} {{/else}} block but that didn't work as well.

Bundle "knockout-es5" ko.track(), etc. in main build

With the alpha the knockout-es5 plugin seems to work fine and with tko I think that this should be part of the standard build. The syntax of declaring a viewmodel as a POJO and optionally making attributes observable is cleaner (and not that this matter too much, more in line with other view libraries). It also of course removes the need for () on observables.

Example:

class App {
  constructor() {
    this.loggedIn = false;
    ko.track(this);
  }
  
  login() {
    this.loggedIn = true;
  }

  logout() {
    this.loggedIn = false;
  }
}

let app = new App();
ko.applyBindings(app);

tko.builder

Further to #39, add tko.builder to compile the generic / custom Knockout instance.

Status of knockout.es5

I use knockout es5 because I prefer the syntax (this.price = 3 vs this.price = ko.observable(3), etc.)

Is the plan for tko to include this syntax natively, or via plugin? In either case, will it be a first class citizen, so that other plugins, e.g. validation, will play nicely with it? (Currently, es5 and validation require some considerable hacking to make them work well together.)

Move to a monorepo

I had separated out the KO scripts into packages to make absolutely certain that the relationships between the packages was logical and minimal (i.e. I couldn't make lazy cross-references ๐Ÿ˜‰ ).

Now that we've got a fairly logical ES6 hierarchy, and I think the essential build tools are set, it might be time to bring it all together.

The most common way to combine multiple packages like this appears to be a monorepo with lerna.

Never having gone down the monorepo path, I have some skepticism, but it's evidently got quite a lot of mindshare.

I wanted to post this issue for two reasons:

  1. Invite any feedback โ€“ any experience with the monorepo design/tools (e.g. lerna); and
  2. So nobody wonders all the repos are being deleted.

Any thoughts: @knockout/core @knockout/extended

Cheers ๐Ÿป

๐ŸŽฅ Incorporate ongoing PRs from Knockout/knockout

From:

$ git log "v3.4.0"..HEAD --oneline

Complete

๐Ÿš€ Merges and goals

Phase 1 - merges

Phase 2 - equivalency

Phase 3 - Toolset and Additions

  • The TKO Policy knockout/tko-policy#1
  • Testing with Jasmine, Mocha, others
  • Document needed polyfills
  • knockout/knockout#1827 Generated documentation/website
  • knockout/knockout#1589 Plugin architecture
  • Incorporate key plugins
    • FastForeach
    • if/else
      • <!-- else --> inside conditional bindings
      • expose conditionals for successive bindings
      • else + elseif binding
    • postprocess binding
    • Knockout Secure Binding
    • Punches
      • filters
      • interpolation
      • namespacing
    • BindingHandler
      • .makeBindingHandler(fn)
      • Promise/resolution of valueAccessor
    • Extender / Promises (cast-Read/Write; thenable; resolveOnRead/Write; .when/.next/โ€ฆ)
    • Postbox
    • ES6 Map/WeakMap

SOLID properties, modularity, and knockout segregation

I just started learning Knockout. I come from a background of highly maintainable and extensible projects. I preach the bible of Bob Martin and his SOLID principles.

I was a little bit confused about how KO purports to be MVVM, yet, in the documentation--and truly, it seems, in implementation--that it appears as though you're attaching view-model assets to the data models; namely observables.

Please excuse me because I definitely could be missing something and I'm definitely, humbly, and deferentially laying this at your feet.

I believe, though, we should be able to have POJO/POTO (Plain Old JavaScript/TypeScript Object) models. We may want to use those models for other things like building a database or other extensible reasons. I considered mapping or separate models for the view and data, but both present the following problem: Those two solutions require updating models in more than one place. I could, with TypeScript, use an interface, but I would still have to update in more than one spot, so I don't relish the prospect any more than the other two options, though, it is type safe.

Another avid KO developer--whom I won't mention, but I will link him this thread and allow him the opportunity to comment if he likes--and I put our heads together and came to the realization that you should be able to bind to the outer object of an instance of a class. He actually started, in earnest, to write something of the sort. The problem, though, he came across is illustrated in this thread and he points to this comment: microsoft/TypeScript#12114 (comment) Apparently it's not yet supported by TypeScript to descend the dependency chain, making deep mapping impossible.

Also, we would need some mechanism to only bind what we need. I suggested something like:

ko.observe(foo, ['name', 'address' ...

but that's hard to do deep comparisons on and is still not DRY code. Possibly class annotations would be better.

One of the main things that I know from preaching SOLID is that frameworks should be abstracted to the max. I may want to replace KO someday with a newer version or another framework. I should be able to have the smallest pieces of my code reliant on KO.

Thanks for listening.

Add `modify` function to observables`

@knockout/core @caseyWebb I'm planning on adding a "modify" function to subscribable.fn, like this:

Object.assign(subscribable.fn, {
  modify (fn, peek) {
    this(fn(peek ? this.peek() : this()))
  }
})

I'm sure this'll be useful for thing like e.g. incrementing obs.modify(x => x + 1), changing case obs.modify(x => x.toUpperCase()).

How does the name modify work? Are there any similar APIs whose naming convention we might borrow? Nothing came to mind so I thought I'd ask.

Does the function itself seem to capture the essence?

Merges from mainline

This issue is just to link commits from knockout that ought to also be merged here.

afterRender / childrenComplete

Analogous to the Knockout 3.5 line:

PRs

[Feature Request] Support ES6 Symbol component names

In larger apps, the ability to register a component using a Symbol would allow you to prevent name-collisions using a pattern as such:

const componentName = Symbol('hello-world')

ko.components.register(componentName, {
    template: 'Hello, World!'
})

ko.applyBindings({
    componentName
})
<div data-bind="component: componentName"></div>

This would be particularly helpful in a situation such as this, the relevant snippet being...

function componentPlugin(route) {
  return (ctx) => ({
    beforeRender() {
      ko.components.register(ctx.pathname, route.component)
      ctx.route.component = ctx.pathname
    },
    afterDispose() {
      ko.components.unregister(ctx.pathname)
    }
  })
}

Where ctx.pathname could be replaced with a unique symbol for that route, without having to use an incrementor.

It could also help break up larger components into sub-components (that won't be used standalone) without polluting the global registry and without the need to add a prefix.

Lastly, it could allow for a more verbose, but idiomatic way of modularizing components. I.E., you could import the symbol for a component instead of just using it's string id (in fairness, you could export the string ID and do the same, but you still run the risk of name-collisions). Having explicit imports for components could help tools like webpack more intelligently bundle, so that you don't have to include all of the components in your entry bundle.

Cannot find closing comment tag to match: ko with: blog

Edit.tmpl.html.tar.gz
After fixing all my click bindings, I'm now getting this error. I'm attaching the view. This works in 3.4.0 and could very well be another thing I'm doing wrong and stupid, or a bug in tko. I went over the view and nothing popped out at my, maybe it will at you. Error and stack below, view attached.

ko.js:898 Uncaught Error: Cannot find closing comment tag to match:  ko with: blog 
    at getVirtualChildren (http://local.north40net.com/node_modules/tko/dist/ko.js:898:17)
    at getMatchingEndComment (http://local.north40net.com/node_modules/tko/dist/ko.js:903:32)
    at nextSibling (http://local.north40net.com/node_modules/tko/dist/ko.js:1013:18)
    at invokeForEachNodeInContinuousRange (http://local.north40net.com/node_modules/tko/dist/ko.js:6236:25)
    at activateBindingsOnContinuousNodeArray (http://local.north40net.com/node_modules/tko/dist/ko.js:6256:15)
    at executeTemplate (http://local.north40net.com/node_modules/tko/dist/ko.js:6331:11)
    at computed.disposeWhen (http://local.north40net.com/node_modules/tko/dist/ko.js:6373:44)
    at Function.evaluateImmediate_CallReadThenEndDependencyDetection (http://local.north40net.com/node_modules/tko/dist/ko.js:2667:105)
    at Function.evaluateImmediate_CallReadWithDependencyDetection (http://local.north40net.com/node_modules/tko/dist/ko.js:2639:31)
    at Function.evaluateImmediate (http://local.north40net.com/node_modules/tko/dist/ko.js:2603:20)
getVirtualChildren @ ko.js:898getMatchingEndComment @ ko.js:903nextSibling @ ko.js:1013invokeForEachNodeInContinuousRange @ ko.js:6236activateBindingsOnContinuousNodeArray @ ko.js:6256executeTemplate @ ko.js:6331computed.disposeWhen @ ko.js:6373evaluateImmediate_CallReadThenEndDependencyDetection @ ko.js:2667evaluateImmediate_CallReadWithDependencyDetection @ ko.js:2639evaluateImmediate @ ko.js:2603evaluatePossiblyAsync @ ko.js:2569notifySubscribers @ ko.js:1743valueHasMutated @ ko.js:1899Observable @ ko.js:1865(anonymous function) @ knockout-amd-helpers.js:189execCb @ require.js:1693check @ require.js:881(anonymous function) @ require.js:1136(anonymous function) @ require.js:134(anonymous function) @ require.js:1186each @ require.js:59emit @ require.js:1185check @ require.js:936enable @ require.js:1173init @ require.js:786(anonymous function) @ require.js:1011(anonymous function) @ require.js:134finishLoad @ text.js:169(anonymous function) @ text.js:205xhr.onreadystatechange @ text.js:317

Typescript support

From #1 , just so I can clean up relevant issues there.


IanYates commented on Jul 6
It really depends on whether we're talking about writing the library in TS or just making it friendly to consume from TS.

The latter is easy - we just need to make a type definition. If this library stays pretty close to KO in terms of a public API surface then it'll have a very similar definition file. I'd be happy to put something together as this takes shape.

If you're talking about writing the library in TS then that's a much bigger discussion. I personally really like it ๐Ÿ˜ but I can understand that many don't.


brianmhunt commented on Jul 6
Consumption will be the goal since I don't know TS. :)

I wonder if there's a way to automate a type definition. What do they look like?
@IanYates


IanYates commented on Jul 6
Automate.. Not that I'm aware of.

Here are some definitions of things with which you're rather familiar

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/cc3d223a946f661eff871787edeb0fcb8f0db156/knockout-secure-binding/knockout-secure-binding.d.ts
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/cc3d223a946f661eff871787edeb0fcb8f0db156/knockout.amd.helpers/knockout-amd-helpers.d.ts
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/cc3d223a946f661eff871787edeb0fcb8f0db156/knockout.postbox/knockout-postbox.d.ts
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/0b20db14dc8d546bd6e8e7b3bcaaf2289f63b55d/knockout.es5/knockout.es5.d.ts
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/cc3b657f2655c8c7cd290ff83dc052be637d8fe2/knockout/knockout.d.ts
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/17fe51d7edd2aab8917d6868b8b69e6014043559/knockout.punches/knockout.punches.d.ts

Also see http://www.typescriptlang.org/docs/handbook/knockout.html for an intro to TS using KO
and
http://www.typescriptlang.org/docs/handbook/writing-declaration-files.html for info about definition files straight from the horse's mouth
๐Ÿ‘ 2

Merging new data with old

One of the drawbacks I've found when using Knockout is when significant portions of a viewModel change as a result of something it is quite difficult to update. My particular example involved changing about 8/9 deeply nested objects (a few of which had observables within them).

I wonder if having some functions to merge a a POJO with an existing objects observables (viewModel) would be helpful / in scope for this project.

components) Add `afterRender`

Per knockout/knockout#1944

Noting comment by @jmvtrinidad on tko.computed issue (pre-monorepo):

Some of the useful callbacks from durandal. canActivate callback allows returning a promise then after promise is resolve, component will start binding or if it was reject, component will cancel rendering. I hope this helps designing callbacks.

Make pureComputed the default

From https://github.com/knockout/tko.computed/issues/1

From knockout/knockout#2167 by @futpib

I'm moving this here since this is where it could be accepted (for ko-4).

Make pureComputed the default computed and make computed impureComputed or even `autorun

I find that, when choosing between pureComputed and computed, pureComputed is almost always the right one due to laziness and performance benefits.

You really want computed only when you want immediate and predictable evaluation for side-effects.

Also you almost certainly want to break your computed in two parts with ignoreDependencies to make sure evaluation happens only when you want:

ko.computed(() => {
    // register dependencies
    ko.ignoreDependencies(() => {
        // produce side-effects
    });
});

This is why I propose that computed is renamed to a longer (and scarier) impureComputed or autorun (like in mobx), possibly changing it's signature dividing "register dependencies" and "produce side-effects" parts. And pureComputed is renamed to computed to make it the go-to option for less experienced knockout.js developers. Of course this would break compatibility, so this is probably only feasible for the next major release.

If we could make documentation advise towards pureComputed and against computed when in doubt, that would be great.

If it were possible to ban any non-local mutation in pureComputed's read and write functions (except writing other observables in write), I'd also root for that.

Experimenting with different renderers

Over the last couple of years some fundamentally different techniques to approaching DOM manipulation / rendering have appeared (e.g. virtual DOM and incremental DOM) and browsers have gained new DOM 'superpowers'. Each technique has shown itself to be better or worse at different types of application and a number of frameworks are currently trying to claim they are the best based on these different rendering styles.

However, Knockout's real skill is in its Observables, not how it updates the DOM.

I see a possibility here, with the componentisation of KO, for some experimentation with different rendering techniques to see whether any of them are better suited to normal KO style apps than the current system. I also think the resulting plug-able architecture would allow those wanting to use KO in different ways to do so but with a different renderer.

The experimentation might also show that less code is needed in KO for things like array change tracking and when DOM content needs re-building during 'with' context changes if something like a virtual or incremental DOM style of rendering was used. I'm not saying it would - but I think it worth the experiment to find out :)

TC39 Proposal - Observable

The TC39 is going to standardize the way Observables should be used. Currently it is in Stage 1 (ready to advance to the next stage) https://github.com/tc39/proposal-observable

Maybe we should take action early on to match tko with the behavior of Observables in the proposal. Would be a huge advantage for tko when the proposal becomes a standard in 1 or 2 years.

Any other forward-ports

@mbest / @knockout/core / @knockout/extended Does anyone see anything committed to Knockout 3.x line that's not been forward-ported?

  1. after-render / childrenComplete
  2. foreach update knockout/knockout#2324
  3. any other plugins (e.g. your switch/case plugin)

Error with .getbindingAccessors

I decided to drop tko into my intranet, by far the biggest project I've used knockout on. I got surprisingly few errors from what I was expecting. But one that repeats is this one.

Uncaught Error: 
SyntaxError Expected ':' but got '=' of 
   'click':function(){window.location.href ='/#/Forum/Details?terms='+ encodeURIComponent($root.terms.peek());}
                                        _/ ๐Ÿ”ฅ \_


    at Parser.parse (http://local.north40net.com/node_modules/tko/dist/ko.js:4069:23)
    at Provider.getBindingAccessors (http://local.north40net.com/node_modules/tko/dist/ko.js:4197:25)
    at computed.disposeWhenNodeIsRemoved (http://local.north40net.com/node_modules/tko/dist/ko.js:4802:98)
    at Function.evaluateImmediate_CallReadThenEndDependencyDetection (http://local.north40net.com/node_modules/tko/dist/ko.js:2667:105)
    at Function.evaluateImmediate_CallReadWithDependencyDetection (http://local.north40net.com/node_modules/tko/dist/ko.js:2639:31)
    at Function.evaluateImmediate (http://local.north40net.com/node_modules/tko/dist/ko.js:2603:20)
    at computed (http://local.north40net.com/node_modules/tko/dist/ko.js:2464:30)
    at applyBindingsToNodeInternal (http://local.north40net.com/node_modules/tko/dist/ko.js:4800:33)
    at applyBindingsToNodeAndDescendantsInternal (http://local.north40net.com/node_modules/tko/dist/ko.js:4590:35)
    at applyBindingsToDescendantsInternal (http://local.north40net.com/node_modules/tko/dist/ko.js:4572:11)Parser.parse
 @ ko.js:4069getBindingAccessors
 @ ko.js:4197computed.disposeWhenNodeIsRemoved
 @ ko.js:4802evaluateImmediate_CallReadThenEndDependencyDetection
 @ ko.js:2667evaluateImmediate_CallReadWithDependencyDetection
 @ ko.js:2639evaluateImmediate
 @ ko.js:2603computed
 @ ko.js:2464applyBindingsToNodeInternal
 @ ko.js:4800applyBindingsToNodeAndDescendantsInternal
 @ ko.js:4590applyBindingsToDescendantsInternal
 @ ko.js:4572applyBindingsToNodeAndDescendantsInternal
 @ ko.js:4599applyBindingsToDescendantsInternal
 @ ko.js:4572applyBindingsToNodeAndDescendantsInternal
 @ ko.js:4599applyBindingsToDescendantsInternal
 @ ko.js:4572applyBindingsToNodeAndDescendantsInternal
 @ ko.js:4599applyBindingsToDescendantsInternal
 @ ko.js:4572applyBindingsToNodeAndDescendantsInternal
 @ ko.js:4599applyBindingsToDescendantsInternal
 @ ko.js:4572applyBindingsToNodeAndDescendantsInternal
 @ ko.js:4599applyBindingsToDescendantsInternal
 @ ko.js:4572applyBindingsToNodeAndDescendantsInternal
 @ ko.js:4599applyBindings
 @ ko.js:4912(anonymous function)
 @ ko.js:6286invokeForEachNodeInContinuousRange
 @ ko.js:6237activateBindingsOnContinuousNodeArray
 @ ko.js:6284executeTemplate
 @ ko.js:6331computed.disposeWhen
 @ ko.js:6373evaluateImmediate_CallReadThenEndDependencyDetection
 @ ko.js:2667evaluateImmediate_CallReadWithDependencyDetection
 @ ko.js:2639evaluateImmediate
 @ ko.js:2603evaluatePossiblyAsync
 @ ko.js:2569notifySubscribers
 @ ko.js:1743valueHasMutated
 @ ko.js:1899Observable
 @ ko.js:1865(anonymous function)
 @ knockout-amd-helpers.js:189execCb
 @ require.js:1693check
 @ require.js:881(anonymous function)
 @ require.js:1136(anonymous function)
 @ require.js:134(anonymous function)
 @ require.js:1186each
 @ require.js:59emit
 @ require.js:1185check
 @ require.js:936enable
 @ require.js:1173init
 @ require.js:786(anonymous function)
 @ require.js:979(anonymous function)
 @ require.js:134(anonymous function)
 @ require.js:1186each
 @ require.js:59emit
 @ require.js:1185check
 @ require.js:936enable
 @ require.js:1173init
 @ require.js:786(anonymous function)
 @ require.js:1011(anonymous function)
 @ require.js:134finishLoad
 @ text.js:169(anonymous function)
 @ text.js:205xhr.onreadystatechange
 @ text.js:317

It seems to me that it is returning improperly escaped strings maybe? It's complaining about this binding
'click':function(){window.location.href ='/#/Forum/Details?terms='+ encodeURIComponent($root.terms.peek());}

And it seems to me if the value was quoted and properly escaped this wouldn't be a syntax error. But I could be missing something else, so I included the entire call stack, and I'm up for any suggestions on how to debug this further.

Here's the relevant html

<ul class="dropdown-menu">
                        <li data-bind="click: function() {window.location.href = '/#/Forum/Details?terms=' + encodeURIComponent($root.terms.peek());}">
                            Search Forums
                        </li>
                    </ul>

bindings) flow control - switch case

Can I plump to have MBest's switch case binding added to the monorepo? While the logic can be accomplished a lot of other ways, it's a really elegant solution for situations involving complex flow control.

knockout.punches throwing error

Just dropping ko.js in place of knockout.js(3.4.0) I'm getting an error with knockout.punches. It looks like this

knockout.punches.js:60 Uncaught TypeError: Cannot read property 'preprocessNode' of undefined(โ€ฆ)addNodePreprocessor
@ knockout.punches.js:60enableInterpolationMarkup
@ knockout.punches.js:525ko_punches.enableAll
@ knockout.punches.js:99(anonymous function)
@ main.js:81runCallbacks
@ domReady.js:24callReady
@ domReady.js:35pageLoaded
@ domReady.js:50

Is there another version of punches? Every project I have literally uses punches as my html template engine, so I can't really test without it without starting a new project from scratch :)

Regression: The parser seems to have troubles with German 'Umlaute'

Observable 'รคhm' works fine with Knockout 3.4 but tko throws an SyntaxError.

tko.js:4428 Uncaught Error:
SyntaxError Bad operator: 'รค'. of
'foreach': รคhm
at Parser.parse (tko.js:4428)
at Provider.getBindingAccessors (tko.js:4556)
at computed.disposeWhenNodeIsRemoved (tko.js:5163)
at Function.evaluateImmediate_CallReadThenEndDependencyDetection (tko.js:2854)
at Function.evaluateImmediate_CallReadWithDependencyDetection (tko.js:2826)
at Function.evaluateImmediate (tko.js:2790)
at computed (tko.js:2651)
at applyBindingsToNodeInternal (tko.js:5161)
at applyBindingsToNodeAndDescendantsInternal (tko.js:4951)
at applyBindingsToDescendantsInternal (tko.js:4933)

Detecting exponential growth computeds

A fairly common problem in my experience is the exponential growth of computed re-computations, particularly in large projects with lots of complex interdependencies.

Sometimes deferred computeds resolve the problem, but sometimes they are not ideal or possible.

I'd like to diagnose when it is a performance issue, and further to be able to isolate it.

My first thought is to overload ko.computed with a rate-sampling on recomputation so e.g.

// globally
const INTERVAL = 60 * 1000
setInterval(checkTicks, INTERVAL)
let ticks = 0

function checkTicks () {
   if (ticks > SOME_RATE) {
     console.info("A computed is very active")
   }
   ticks = 0
}

// overload the computeds' readFunction so
state.readFunction = () => {
   ticks ++
   theOriginalReadFunction()
}

This is the most basic part, simply telling the user that there's a large number of recomputations.

It may be possible to use the computeds _version for this, and similarly have an extender (but part of the issue is globally identifying what computed is the problem).

@knockout/core thoughts?

Request: support for passive events

Passive event listeners, especially for the mouse wheel event, have landed and established in most of the major browsers by now. We should consider adopting that into the event binding-handler. I suggest an API like that:

<div data-bind="event: {wheel: {handler: handleWheel, passive: true}}"></div>

or shorter, but less generic:

<div data-bind="passiveEvent: {wheel: handleWheel}"></div>

@brianmhunt, thoughts?

What about a validation plugin?

Have you thought about adding a validation plugin to tko? Something similar to Knockout-Validation.

I really believe that this would be a major addition to the project because:

  • almost all production ready environments needs some kind of client-side validation
  • most client-side frameworks (e.g. Aurelia, Angular) support it
  • the Knockout-Validation has been numb for a while
  • I'm stretching a bit here but I think it fits the goals of knockout:

(...) along with a powerful and extensible set of declarative bindings to enable productive development.

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.