2

I have a simple model, and on there is an observable ("model.thing"). I then set an additional observable on this ("someProp") and pass it into the params of a component.

model.thing = ko.observable({});
model.thing.someProp = ko.observable("Yolo");

At this point the observable has become a computed and i'm not sure why.

If i change the model so that instead of having model.thing as an observable i have it as a simple object and then pass that in, it is coming through without changing into a computed...

Does anyone have an explanation for this behaviour?

Here's a working example (it alerts the param which shows that it has become a computed).

http://liveweave.com/MozLiW

var viewModel = function() {
    var model = {};
 model.thing = ko.observable({}); //when thing is observable
   //model.thing = {};
 model.thing.someProp = ko.observable("Yolo");
 
    
  return model;
};

ko.components.register('custom-element', {
    viewModel: function(params) {
        this.value = params.value;
       alert(this.value); //then this is dependent, why?!
    }, 
    template:
    '<div data-bind="text: value"></div>'
});

ko.applyBindings(viewModel);
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>

<title>Knockout component</title>
</head>
<body>
  <custom-element params="value: thing().someProp"></custom-element>
<!--   
<custom-element params="value: thing.someProp"></custom-element> -->

</body>
</html>
4imble
  • 13,979
  • 15
  • 70
  • 125
  • 1
    See: http://www.knockmeout.net/2014/06/knockout-3-2-preview-components.html **How params are passed to the component** for the explanation of this behavior. – nemesv Feb 27 '15 at 10:46
  • I see thanks, so in order to solve the problem this was providing me (setting the value), i will need to use params.$raw.value(); Many thanks. – 4imble Feb 27 '15 at 10:53

1 Answers1

1

Thanks to nemesv, he pointed me to this which explains it.

The 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:

<my-component params="value: selectedItem().value"></my-component>

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.

4imble
  • 13,979
  • 15
  • 70
  • 125