component binding vs. custom element parameter differences

53 views
Skip to first unread message

Noirabys

unread,
May 5, 2015, 9:00:44 AM5/5/15
to knock...@googlegroups.com
Hi,
i would expect that params in a component binding behave the same like params in a custom element,
but there is a difference: 
have a look at  the following example: result of component binding looks fine for me, but the custom element doesn't: 


<body>

<div data-bind="component: { name:'my-component', params: {title: title() + 'vv'}  }"></div>
<my-component params="title: title()+'aa'"></my-component>

<script>
  
  function ViewModel(data){
    var self = this;
    self.title = ko.observable(data.title);
  }
  
  model = new ViewModel({ title: 'my title:'});
  
  function MyComponent(data){
    self.title = ko.observable(data.title);
  }
  
  ko.components.register('my-component', {
    template: '<h1 data-bind=\'text: title\'></h1>',
    viewModel: MyComponent
  });
   
  ko.applyBindings(model);
  
</script>
         
</body>


Result:

my title:vv

function f(){if(0<arguments.length){if("function"===typeof O)O.apply(d, arguments);else throw Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");return this}a.k.Jb(f);n&&k(!0);return q}



whats the reason for using different snytax in the component binding and the custom element ?

best regards,
 noirabys

Michael Best

unread,
May 5, 2015, 6:17:40 PM5/5/15
to knock...@googlegroups.com
You can read about the design decisions here: https://github.com/knockout/knockout/pull/1385

To work around this issue, you'll probably want to include some conditionals in your component code:

self.title = ko.isObservable(data.title) ? data.title : ko.observable(data.title);

-- Michael

Michael Best

unread,
May 5, 2015, 6:19:05 PM5/5/15
to knock...@googlegroups.com
Actually maybe just use ko.unwrap:

self.title = ko.observable(ko.unwrap(data.title));

It depends on how you want to respond to changes in the parameters.

-- Michael

Noirabys

unread,
May 6, 2015, 3:35:30 AM5/6/15
to knock...@googlegroups.com
thanks for reply and the link!

i've read the design decisions and now it's clear why and when a computed is used, but i didn't find a hint why it behaves different in 
the component binding and the custom element! in case that the component binding is used, shouldn't be the implementation of how parameters passed to the component model 
be the same?


yes,
 unwrap is what i use right now as a workaround

i think in most cases i would not use a component model at all, because it is another design pattern which doesn't fit to the viewmodel pattern. (business model vs. gui model)

Instead of that approach i use a pattern, which i call "custom binding context":

1. abstraction of the behaviour into a model, for example a 
   LinearNavigation with next, prev, isFirst, isLast methods
2. data-bind="navi: { model: LinearNavigationModelOrInstance , data: objectOrWhatEverToNavigateOn }
3. expose api of the navigation model as context lets say $navi:
4. use the api on the new custom binding context 
  for example  data-bind="click: $navi.next" 

this pattern makes it easy to change the behaviour model
and it keeps the business model (viewmodel) free of gui logic.

greetings, 
 noirabys









greetings,
 noirabys
Reply all
Reply to author
Forward
0 new messages