سؤال

I am writing Jasmine test that is using mocked database response from WebSQL database. In following code segment I am getting an error.

        function createCalculatedField(calculatedValue, objectContext) {
    var computedObservable = ko.computed({
        read: function () {
            return ko.unwrap(ko.bindingProvider.instance.parseBindingsString("text: " + calculatedValue, objectContext).text);
        },
        write: function (value) {
            computedObservable.notifySubscribers(value);
        },
        owner: objectContext
    });

error message I am getting is following:

ReferenceError: Unable to parse bindings. Bindings value: text: ko.unwrap(PagingStartIndex) + $context().length Message: $data is not defined

I have printed out function inputs, and reproduced the error into Chrome console in screenshot below.

enter image description here

upon inspection of knockout-3.0.0.custom.min.js parseBindingsString method on which it fails.

function (b,c,d,e){try{var f=this.bindingCache,h=b+(e&&e.valueAccessors||""),g;if(!(g=f[h])){var n,k="with($context){with($data||{}){return{"+a.expressionRewriting.preProcessBindings(b,e)+"}}}";n=new Function("$context","$element",k);g=f[h]=n}return g(c,d)}catch(p){throw p.message="Unable to parse bindings.\nBindings value: "+
b+"\nMessage: "+p.message,p;}}

I can see that $data is internal knockout.js parameter. This same code works just fine in production environment, so I am assuming I am not setting something somewhere, could you point me in direction on how to debug this issue, cause I am totally out of ideas at this point.

هل كانت مفيدة؟

المحلول

Internally, Knockout uses the following dynamic function to evaluate your expression

function($context, $element) {
  with($context) {
    with($data||{}) {
      return {text: ko.unwrap(PagingStartIndex) + $context().length};
    }
  }
}

If you look at the object that is normally passed into the parseBindingsString by knockout it looks like...

{
  $data: {...},
  $index: ko.observable(),
  $parent: {...},
  $parentContext: ko.bindingContext,
  $parents: [...],
  $root: {...}
}

This object graph is normally created by invoking new ko.bindingContext(...) or, if you are within a custom binding, bindingContext.createChildContext(...)

Looking at your screenshot it looks like objectContext is an observableArray containing 2 elements and I'm also assuming you manually created the objectContext instance in your jasmine tests.

Therefore the object you are passing into the parseBindingString ( which comes into the dynamic function as $context ) does not have a $data field, that is the reason the exception is thrown.

The should have the object graph similar to the normal bindingContext object where the value of $data is your model

i.e.

{
  $data: ko.observableArray: ( [
  {
    Fields:{...}, 
    Insert: false, 
    SetFields:[]
  }, {
    Fields:{}, 
    Insert: false, 
    SetFields: [] 
  }] ),
  $index: ko.observable(),
  ...
}

However, you will still get an error message in this instance as PagingStartIndex is missing from $data object, the same as if you got a mismatch between your binding expression and the model in your production system.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top