Knock Me Out
Time 2021-11-07 13:10:01Web Name: Knock Me Out
WebSite: http://www.knockmeout.net
ID:224623
Keywords:
Knock,Me,Out,Description:
keywords: description:Hello! Are you currently developing with Knockout? Much has changed in the landscape of client-side libraries since Knockout was considered a …Hello! Are you currently developing with Knockout? Much has changed in the landscape of client-side libraries since Knockout was considered a popular choice, but there still seem to be many successful projects using it today. I would love to hear about the interesting things that you are building with Knockout in 2019.
For the last several years, I have been working with React on the front-end (and Node on the server-side) while working on LeanKit. So, while I have been having lots of fun with JavaScript, I havent had a chance to do anything new with Knockout lately. I would really enjoy spending time getting caught up and helping out in the Knockout world.
Looking for feedback on these questions:What would be useful for me to spend some time on?What are your biggest challenges with Knockout in 2019?Are there new plug-ins that could be created to solve a problem?Should I update many of my existing libraries to have modern code and a up-to-date build system?Any other ideas come to mind?Reply in the comments or send me an email at Thanks!
Knockout 3.3 is available now! This release features some nice refinements to the components functionality along with a number of other small enhancements and bug fixes. The full release notes can be found here.
In this release cycle, we welcomed Brian Hunt to the core team and he has brought some great energy and contributions to the project. Steve and Michael once again made the bulk of the major changes in this release along with a number of other pull requests from the community.
Components refinementsWe received lots of great feedback regarding Knockouts component functionality. Many developers seem to be having great success using this style of development. For 3.3, we focused on a few low-level enhancements that should provide some increased flexibility.
Synchronous FlagComponents were always rendered asynchronously previously, even when the template/viewModel were already cached. Now, the component registration can include a synchronous flag to indicate that the component should render synchronously, if it can. In the case where you have many nested components, this can help alleviate issues with reflows and/or flickering while rendering. The syntax would look like:
Working with component child nodesIn Knockout 3.3, you now have options for working with the child nodes contained inside of a component. There are three enhancements that go together targetting this area:
1- The template
binding can accept an array of DOM nodes directly via a nodes
option
2- If you are using a createViewModel
function for your component, it will now receive the child nodes and you can determine how to expose them on your components view model for binding against the template binding
3- There is a new $componentTemplateNodes
context variable that contains the nodes directly. In normal cases, this will allow you to avoid exposing DOM nodes in your view model and bind in the template directly.
For example, a component template might simply want to add some wrapping markup like:
You could then add the component to your page:
If would still be possible to manipulate (slice
) $componentTemplateNodes
directly in the binding, depending on the complexity of the markup/scenario.
$component
context variableSometimes inside of a components template, when looping through nested structures, you may want to bind up to the root of the component. Rather than trying to manage $parents[x]
, you can now use $component
to get the nearest components root. This is a similar concept to $root
for the entire application, but is specific to a component.
A few other enhancements that I think are interesting:
awake/sleep notifications from pure and deferred computedsYou can now subscribe to notifications from a pureComputed
for when it wakes up and for when it goes to sleep (when nothing depends on it). Additionally, a deferred computed now notifies when it wakes up as well. The subscriptions would look like:
ko.ignoreDependencies(callback, callbackTarget, callbackArgs)
- executes a function and ignores any dependencies that may be encountered. This can be useful sometimes in a computed observable or in a custom binding when you want to execute code, but not trigger updates when any dependencies from that code change. You would use it like:ko.utils.setTextContent(element, textContent)
handles cross-browser setting the text of a node and handles virtual elementsFixes3.3 also includes a number of nice fixes and performance improvements listed here. This includes making the css
binding work properly with SVG elements, which has been a long-standing issue.
Please check out Knockout 3.3.0 today! It is available from GitHub, the main site, Bower (bower install knockout
), and NPM (knockout).
Last summer, I had the opportunity to speak at ModernWebConf, ThatConference, and devLink on the topic of browser memory leaks. The talk was focused on the tools and techniques that you can use for memory leak testing and situations in JavaScript that comonly cause these leaks. Slides for the presentation can be found here.
With the rise of single-page applications and increased complexity (and amount) of JavaScript on the client-side, memory leaks are a common occurrence. Knockout.js applications are not immune to these problems. In this post, I will review some scenarios that often contribute to memory leaks and discuss the APIs in Knockout that can be used to prevent and resolve these issues.
The main source of leaks in KOMemory leaks in KO are typically caused by long-living objects that hold references to things that you expect to be cleaned up. Here are some examples of where this can occur and how to clean up the offending references:
1. Subscriptions to observables that live longer than the subscriberSuppose that you have an object representing your overall application stored in a variable called myApp
and the current view as myViewModel
. If the view needs to react to the apps language observable changing, then you might make a call like:
What this technically does is goes to myApp.currentLanguage
and adds to its list of callbacks with a bound function (languageHandler
) that references myCurrentView
. Whenever myApp.currentLanguage
changes, it notifies everyone by executing each registered callback.
This means that if myApp
lives for the lifetime of your application, it will keep myCurrentView
around as well, even if you are no longer using it. The solution, in this case, is that we need to keep a reference to the subscription and call dispose
on it. This will remove the reference from the observable to the subscriber.
In this case, the userStatusText
computed references myApp.currentUser()
. As in the subscription example, this will add to the list of callbacks that myApp.currentUser
needs to call when it changes, as the userStatusText
computed will need to be updated.
There are a couple of ways to solve this scenario:
we can use thedispose
method of a computed, like we did with a manual subscription.in KO 3.2, a specialized computed called a ko.pureComputed
was added (docs here). A pure computed can be created by using ko.pureComputed
rather than ko.computed
or by pasing the pure: true
option when creating a normal computed. A pure computed will automatically go to sleep (release all of its subscriptions) when nobody cares about its value (nobody is subscribed to it). Calling dispose
on a pure computed would likely not be necessary for normal cases, where only the UI bindings are interested in the value. This would work well for our scenario where a temporary view needs to reference a long-living observable.3. Event handlers attached to long-living objectsIn custom bindings, you may run into scenarios where you need to attach event handlers to something like the document
or window
. Perhaps the custom binding needs to react when the browser is resized. The target needs to keep track of its subscribers (like an observable), so this will create a reference from something long-living (document
/window
in this case) back to your object or element that is bound.
To solve this issue, inside of a custom binding, Knockout provides an API that lets you execute code when the element is removed by Knockout. Typically, this removal happens as part of templating or control-flow bindings (if
, ifnot
, with
, foreach
). The API is ko.utils.domNodeDisposal.addDisposeCallback
and would be used like:
If you did not have easy access to the actual handler attached, then you might consider using namespaced events like $(window).on("resize.myPlugin", handler)
and then remove the handler with $(window).off("resize.myPlugin")
.
The above issue is also commonly encountered when using custom bindings to wrap third-party plugins/widgets. The widget may not have been designed to work in an environment where it would need to be cleaned up (like a single-page app) or may require something like a destroy
API to be called. When choosing to reference third-party code, it is worthwhile to ensure that the code provides an appropriate method to clean itself up.
dispose
function. Can be called on a manual subscription or computed to remove any subscriptions to it.
ko.utils.domNodeDisposal.addDisposeCallback
- adds code to run when Knockout removes an element and is normally used in a custom binding.
ko.pureComputed
- this new type of computed added in KO 3.2, handles removing subscriptions itself when nobody is interested in its value.
disposeWhenNodeIsRemoved
option to a computed - in some cases, you may find it useful to create one or more computeds in the init
function of a custom binding to have better control over how you handle changes to the various observables the binding references (vs. the update
function firing for changes to all observables referenced. This technique can also allow you to more easily share data between the init
function and code that runs when there are changes (which normally would be in the update
function.
For example:
Note that the example is passing in the disposeWhenNodeIsRemoved
option to indicate that these computeds should automatically be disposed when the element is removed. This is a convenient alternative to saving a reference to these computeds and setting up a handler to call dispose
by using ko.utils.domNodeDisposal.addDisposeCallback
.
One pattern that I have used in applications when I know that a particular module will often be created and torn down is to do these two things:
1- When my module is being disposed, loop through all top-level properties and call dispose
on anything that can be disposed. Truly it would only be necessary to dispose items that have subscribed to long-living observables (that live outside of the object itself), but easy enough to dispose of anything at the top-level when some have created external subscriptions.
2- Create a disposables
array of subscriptions to loop over when my module is being disposed, rather than assigning every subscription to a top-level property of the module.
A snippet of a module like this might look like:
ConclusionMemory leaks are not uncommon to find in long-running Knockout.js applications. Being mindful of how and when you subscribe to long-living observables from objects that are potentially short-lived can help alleviate these leaks. The APIs listed in this post will help ensure that references from subscriptions are properly removed and your applications are free of memory leaks.
Knockout 3.2 will include some exciting new functionality out-of-the-box to do modular development through creating components. From Knockouts point of view, a component allows you to asynchronously combine a template and data (a view model) for rendering on the page. Components in Knockout are heavily inspired by web components, but are designed to work with Knockout and all of the browsers that it supports (all the way back to IE6).
Components allow you to combine independent modules together to create an application. For example, a view could look like:
The idea of doing modular development with Knockout is certainly not a new one. Libraries like Durandal with its compose
binding and the module
binding from my knockout-amd-helpers have been doing this same type of thing for a while and have helped prove that it is a successful way to build and organize Knockout functionality. Both of these libraries have focused on AMD (Asynchronous Module Definition) to provide the loading and organization of modules.
Knockouts goal is to make this type of development possible as part of the core without being tied to any third-party library or framework. Developers will be able to componentize their code, by default, rather than only after pulling in various plugins. However, the functionality is flexible enough to support different or more advanced ideas/opinions through extensibility points. When KO 3.2 is released, developers should seriously consider factoring components heavily into their application architecture (unless already successfully using one of the other plugins mentioned).
How does it work?By default, in version 3.2, Knockout will include:
a system for registering/defining componentscustom elements as an easy and clean way to render/consume a componentacomponent
binding as an alternative to custom elements that supports dynamically binding against componentsextensibility points for modifying or augmenting this functionality to suit individual needs/opinionsLets take a look at how this functionality is used:
Registering a componentThe default component loader for Knockout looks for components that were registered via a ko.components.register
API. This registration expects a component name along with configuration that describes how to determine the viewModel
and the template
. Here is a simple example of registering a component:
new
).can pass an instance
property to use an object directly.can pass a createViewModel
property to call a function that can act as a factory and return an object to use as the view model (has access to the DOM element as well for special cases).can pass a require
key to call the require
function with the supplied value. This will work with whatever provides a global require function (like require.js
). The result will again go through this resolution process.Additionally, if the resulting object supplies a dispose
function, then KO will call it whenever tearing down the component. Disposal could happen if that part of the DOM is being removed/re-rendered (by a parent template or control-flow binding) or if the component binding has its name changed dynamically.
element
property that supplies the id of an element to use as the templatecan be an element
property that supplies an element directlycan be a require
property that like for viewModel
will call require
directly with the supplied value.A component could choose to only specify a template
, in cases where a view model is not necessary. The supplied params will be used as the data context in that case.
With this functionality, Knockout will provide a component
binding as an option for rendering a component on the page (with the other option being a custom element). The component binding syntax is fairly simple.
The component binding supports binding against an observable and/or observables for the name
and params
options. This allows for handling dynamic scenarios like rendering different components to the main content area depending on the state of the application.
While the component binding is an easy way to display a component and will be necessary when dynamically binding to components (dynamically changing the component name), custom elements will likely be the normal way for consuming a component.
Matching a custom element to a componentKnockout automatically does all of the necessary setup to make custom elements work (even in older browsers), when ko.registerComponent
is called. By default, the element name will exactly match the component name. For more flexibility though, Knockout provides an extensibility point (ko.components.getComponentNameForNode
) that is given a node and expected to return the name of the component to use for it.
The params are provided to initialize the component, like in the component binding, but with a couple of differences:
If a parameter creates dependencies itself (accesses the value of an observable or computed), then the component will receive a computed that returns the value. This helps to ensure that the entire component does not need to be rebuilt on parameter changes. The component itself can control how it accesses and handles any dependencies. For example, in this case:The component will receive a params object that contains a name
property that is supplied as a computed in this case. The component can then determine how to best react to the name
changing rather than simply receiving the result of the expression and forcing the entire component to re-load on changes to either of the observables.
params
object supplied when using the custom element syntax will also include a $raw
property (unless the params
happens to supply a property with that same name) which gives access to computeds that return the original value (rather than the unwrapped value). For example:In this case, since selectedItem
is accessed, the param is supplied as a computed. When the computed is accessed, the unwrapped value
is returned to avoid having to double-unwrap a param to get its value. However, you may want access to the value
observable in this case, rather than its unwrapped value. In the component, this could be achieved by accessing params.$raw.value()
. The default functionality is slanted towards ease of use (not having to unwrap a param twice) while providing $raw
for advanced cases.
Knockout lets you add multiple component loaders that can choose how to understand what a component is and how to load/generate the DOM elements and data.
A loader provides two functions: getConfig
and loadComponent
. Both receive a callback argument that is called when the function is ready to proceed (to support asynchronous operations).
getConfig
can asynchronously return a configuration object to describe the component given a component name.loadComponent
will take the configuration and resolve it to an array of DOM nodes to use as the template and a createViewModel
function that will directly return the view model instance.The default loaderTo understand creating a custom component loader, it is useful to first understand the functionality provided by the default loader:
The default getConfig
function does the following:
The default loadComponent
function does the following:
viewModel
and template
portions of the config based on the various ways that it can be configured.if using require
will call require
with the configured module name and will take the result and go through the resolution process again.when it has resolved the viewModel
and template
it will return an array of DOM nodes to use as the template and a createViewModel
function that will return a view model based on however the viewModel
property was configured.A sample custom loaderLets say that we want to create a widget
directory where we place templates and view model definitions that we want to require via AMD. Ideally, we want to just be able to do:
In this case, we could create a pretty simple loader to handle this functionality:
In this custom loader, we just dynamically build the configuration that we want, so we dont necessarily have to register every widget as its own component, although registering will properly setup custom elements to work with the component. Loading the widget-one
component would load a one.js
view model and one.tmpl.html
template from a widgets
directory in this sample loader. If the component is not a widget, then the callback is called with null
, so other loaders can try to fulfill the request.
Components are a major addition to Knockouts functionality. Many developers have found ways to do this type of development in their applications using plugins, but it will be great to have standard support in the core and the possibility for extensibility on top of it. Steve Sanderson recently did a great presentation at NDC Oslo 2014 that highlighted the use of components in Knockout. Check it out here.
Knockout 3.2 is well underway and should be ready for release this summer.
I received a question over email asking about how Knockouts dependency detection actually works and thought that I would share an answer in this post. I know that I feel a bit uncomfortable whenever a library that I am using does something that I dont fully understand, so I hope that I can help ensure that this part of Knockout is not misunderstood or considered magic.
A few questions to answer:For a computed observable, how does KO know which dependencies should trigger a re-evaluation of the computed on changes?How is it possible for the dependencies to change each time that a computed is evaluated?For bindings, how are dependencies tracked?Determining dependencies for a computedTLDR: Knockout has a middle-man object that is signalled on all reads to computed/observables and tells the current computed being evaluated that it might want to hook up a subscription to this dependency.
Internally Knockout maintains a single object (ko.dependencyDetection
) that acts as the mediator between parties interested in subscribing to dependencies and dependencies that are being accessed. Lets call this object the dependency tracker.
In a block of code that wants to track dependencies (like in a computeds evaluation), a call is made to the dependency tracker to signal that someone is currently interested in dependencies. As an example, lets simulate what a computed would call:
Any read to an observable or computed triggers a call to the dependency tracker. A unique id is then assigned to the observable/computed (if it doesnt have one) and the callback from the currently interested party is passed the dependency and its id.The dependency tracker maintains a stack of interested parties. Whenever a call is made to start tracking, a new context is pushed onto the stack, which allows for computeds to be created inside of computeds. Any reads to dependencies will go to the current computed being evaluated.When a computed is done evaluating, it signals the dependency tracker that is is complete and the tracker pops the context off of its stack and restores the previous context.When an observable/computed dependency is updated, then the subscription is triggered and the computed is re-evaluated.Here is a jsFiddle version of this code: http://jsfiddle.net/rniemeyer/F9CrA/. Note that ko.dependencyDetection
is only exposed in the debug build. In the release build it is renamed as part of the minification process.
So, Knockout doesnt need to parse the function as a string to determine dependencies or do any tricks to make this happen. The key is that all reads to observable/computeds go through logic that is able to signal the dependency tracker who can let the computed know to subscribe to the observable/computed.
How can dependencies change when a computed is re-evaluated?Each time that a computed is evaluated, Knockout determines the dependencies again. For any new dependencies, a subscription is added. For any dependencies that are no longer necessary, the subscriptions are disposed. Generally, this is efficient and beneficial as long as you are only branching in computed code based either data that is observable or doesnt change. For example:
In this example, when showErrors
is false, this computed will only have a single dependency, showErrors
. There is no need to depend on the history or trigger re-evaluation when the items change, as it will not influence the result of the function. If showErrors
does become truthy, then the computed will depend on showErrors
, the history
observableArray, and the type
of each item.
Bindings in Knockout actually use computeds as a tool to facilitate their own dependency tracking. Each binding is evaluated within a computed observable for this purpose. Observables/computeds accessed in the update
function of a binding become dependencies. Observables that are accessed within a binding string (like items
in data-bind="if: items().length"
) are read when the valueAccessor()
function is called (or via allBindingsAccessor
- allBindingsAccessor.get("if")
in this case). I think that it is useful to think of a bindings update
function just like a normal computed observable where access to any dependencies will trigger the binding to run again.
Note: Prior to KO 3.0, all bindings on a single element were wrapped inside of a single computed. The parsing and evaluation of the binding string was also included in this computed. So, calling valueAccessor()
would give the result of the expression rather than actually run the code. Dependency detection worked the same way, all bindings on an element were triggered together and it was not possible to isolate dependencies made in the binding string. See this post for more details.
There is an interesting feature coming in KO 3.2 related to computed dependency tracking. Michael Best implemented an option that allows a computed to not maintain any dependencies when it has no subscribers to it. This is not appropriate for all cases, but in situations where the computed returns a calculated value with no side-effects, if there is nothing depending on that calculated value, then the computed can go to sleep and not maintain subscriptions or be re-evaluated when any of the dependencies change. This will be useful for efficiency as well as potentially preventing memory leaks for a computed that was not disposed, but could be garbage collected if it was not subscribed to something observable that still exists. The option is called pure
and a ko.pureComputed
is provided as a shortcut.
Father, husband, programmer and a positive guy. Never short on ideas. Love to learn and collaborate.
Follow @rpniemeyer rniemeyer on Github email: ryan at knockmeout.net<<< Thank you for your visit >>>
Hello! Are you currently developing with Knockout? Much has changed in the landscape of client-side libraries since Knockout was considered a …Websites to related : Yoga Tourism
keywords:
description:
keywords:
description:
Web Analysis for Ambassadorbibleuniversity - ambassadorbibleuniversity.org
keywords:
description:
TeenMegaWorld.netJoin nowJoin NowInstant AccessContact & SupportPrivacy PolicyTerms & ConditionsWebmastersPlease visit Fxbillin
keywords:invitations naperville, invitations holiday, gala invitation, wedding invitations, custom invitations, wedding invitation, wedding program, u
babblers.net keywords:
description:
keywords:
description:
(407) 742-5000 Feedback
keywords:Xlab,UC Berkeley,University of California,Berkeley,Experimental Social Science Laboratory,Participate,Research,Sona Systems,Sona
description:
keywords:
description:
HomeWorkSketch BookFrankAboutContact Select Page
keywords: TripADeal, travel deals
description:Find great deals & holiday packages at amazing prices with award-winning online travel agent TripADeal.
keywords:
description:GBC is a Chicago intellectual property law firm. We specialize in patent, trademark, and copyright procurement and enforcement;
Hot Websites