0
votes

I am having trouble with a component: the template does not seem to bind to the values in the ViewModel.

This is where the action begins

<div data-bind="foreach: orderItem">
  <item-widget params="productname: Product,
                       casetopallet: CaseToPallet,
                       requiredcases: RequiredCases,
                      "></item-widget>
</div>


<div class="OrderItem"> 
<input class="locknumin" type="number" data-bind="attr: {value: collectedCases}"></input>
<input class="locknumin" type="number" data-bind="attr: {value: requiredCases}"></input>
<input class="locknumin" type="number" data-bind="attr: {value: collectedPallets}"></input>
<input class="locknumin" type="number" data-bind="attr: {value: requiredPallets}"></input>
<input type="text" data-bind="attr: {value: $component.productName}"></input>
</div>

When params key == the attribute binding everything shows up ok except when I attempt to use a computable which will not display itself while the rest will.

function OrderItemVeiwModel(params) {
    var self = this;
    self.productName = ko.observable(params.productname);
    self.caseToPallet = ko.observable(params.casetopallet);
    self.requiredCases = ko.observable(params.requiredcases);
    self.collectedCases = ko.computed();
    self.collectedPallets = ko.observable();
    self.requiredPallets = ko.observable(function(){return this.collectedCases / this.casetoPallet;})
}; 
ko.components.register('item-widget', {veiwModel: OrderItemVeiwModel, template:{element: OrderItemTemplate}});

But the computed value is never displayed. To see what is going on I changed all the param keys so that the ViewModel can access them but not the template and nothing is displayed.

The question is: should I be expecting the view to bind on the veiwModel data here, or do I have to create the component some other way? Or is there a simple mistake I've made?

Also are there any debuggers I can use in javascript that would allow me to peek at object values so that I can look into these things myself.

==================================edit======================================== I have had a look with the debug version of knockout and chromium dev utils (Much better than fireFoxes) the error happens in

ko.bindingHandlers.attr.update 

when it tries to unwrap the observables. So at least I know that the binding is from the model to the veiw. I will have to try fleshing out the veiwModel with an init or something as it is clearly not in the binding context as is; or perhaps setting up bindings manually. Thanks for the reply s I am afraid I may be a little to stuck on this incorrect method of component creation because it looks quite simple and neat. ps I have tried self, observable, non observable, bind(this/self) using only one value in the vm and pretty much all possible combinations of $data $ components on only one veiwmodel value

1
The computed should be defined with a function as its parameter. What are you expecting it to display? - Roy J
Ahh sorry the computed I am referring to is requiredPallets I did a bit of playing about with the code after discovering the problem before posting I am trying atm to display well any value atm getting the veiwmodels data bound to the veiw computed or not - goodlymcnotroublehere
Try using self instead of this in requiredPallets. - Roy J
In addition, invoke the observables (with no args) as a function to get their value. - Jeroen
I have had a look with the debug version of knockout and chrome dev utils (Much better than fireFoxes) the error happens in ko.bindingHandlers.attr.update when it tries to unwrap the observables so at least I know that the binding is from the model to the veiw. (at one point I considered the possibility that all keys in the veiw and params had to be the same as the veiws bindings using params a an internal message passing point ) - goodlymcnotroublehere

1 Answers

0
votes

It is hard to understand what you want to achieve but what I can see is that your implementation of the component has some problems.

  1. self.productName = ko.observable(params.productname); - It should be self.productName = params.productname; because the Product you supply should be an Observable. In you AppModel you should define it like self.Product = ko.observable();

  2. self.collectedCases = ko.computed(); - a Computed without a function that supplies the computed result makes no sense. It should always be something like self.collectedCases = ko.computed(function () { return ...; });

  3. self.requiredPallets = ko.observable(function(){return ...;}) - should be ko.computed(...), not ko.observable(...), see my 2nd point.

  4. function(){return this.collectedCases / this.casetoPallet;} - you should use self. here instead of this.