New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhanacement: Allow Parameter-Driven Config for Knockout Components #1656
Comments
@mstarets you may want to have a look at the "custom loader" extensibility point available for the components functionality.
Hope that helps! |
Thanks, Ryan. I was aware of your blog (I am a fan ;)) This solution definitely works, but I am trying avoid having to encode the name of the module into the component name. Having configParams would provide a cleaner solution, and it would enable extra features, such as specifying template name that is different from the ViewModel module name. Thanks, |
This is interesting. The thing that might be tricky here is that, by design, component definitions are cached so that the loader only needs to get invoked the first time any given named component is requested. This guarantees that there's only one async load process, so it's very hard to have any pathologically bad cases like a Having this The current design of requiring you to encode everything unique about the component definition into its name ensures that the caching behavior always lines up with what the developer is requesting. Arguably this is correct, and in your case you should create fake "component names" that encode all of the @mstarets, do you have any other views on how this should interact with component definition caching? |
Steve, I suspected there was a good reason why the 'name' parameter was treated specially. Thanks for explaining it. The only workable solution I could see would be to document that caching of component definitions is only enabled if configParams is not specified or if configParams['definitionCacheKey'] is provided. I am now thinking that my use case is not what Knockout Components Design should really target. That use case was automation of region navigation within a single-page application. The 'module' binding in AMD Helpers does a very good job with that, but it lacks certain features that are supported by Durandal Views (lifecycle events, view caching, etc.), and it has some problems like the lack of concurrency in fetching of template and ViewModel definitions (see rniemeyer/knockout-amd-helpers#29). Rather than complicating Knockout Components, I think I would now prefer to see the 'module' binding implemented by Core Knockout. Thanks, |
[As of v3.4.0] I initially followed the custom loader instructions, but the custom elements wouldn't processed by Knockout without pre-registration of their corresponding components, so I dug further and realized that I have to override the default This approach allows lazy load of the components using custom element (tag) as they appear in the markup templates, without having to explicitly pre-register them. Further, using the text plugin of requirejs r.js optimizer is able to package the whole component into 1 bundle for production build. Original
What I did:
Example of a component module, using a helper util JSFace (https://github.com/tnhu/jsface) for class construction
|
I feel that Knockout already provides good component extensibility, and the needs described can be satisfied using the existing features. |
I understand that Knockout Components were in many ways inspired by the Knockout AMD Helpers. In most cases, one can easily switch to using Knockout Components, but there i still one use case where AMD Helpers sfits better than core Knockout Components: loading dynamic markup from arbitrary external files. Suppose you are writing a single-page application where the center area is populated dynamically depending on the menu choice made by the user. If the user selects 'Billing', we want to load the billing sup-page along with its associated View Model. This can be easily achieved with the 'module' binding from AMD helpers (the name of the module can be specified as an observable), but with Knockout Components you would have to pre-register the 'Billing' page as a Knockout component. This is very inconvenient for metadata-driven applications or for applications with lots of pages maintained by different developers.
Would it be possible possible to add a new 'configParams' attribute on the component binding? The object would then be passed to the getConfig() method on the loader. This would enable creation of a Knockout component that would replace the 'module' binding from AMD Helpers:
And the custom loader's getConfig() would look similar to the following:
getConfig: function(name, configParams, callback) {
var moduleName = ko.utils.unwrapObservable(configParams['name']);
Another alternative would be to pass the existing 'params' value into the getConfig(), but that would mean that we are mixing module config parameters with the parameters for the module itself.
And yet another alternative would be to create a new 'generic module' binding that would share 99% of its code with the component binding.
Thanks!
The text was updated successfully, but these errors were encountered: