What is the easiest way to change data in one of t

2020-02-01 18:29发布

问题:

I am running (my own built) KnockOut.JS application. What is the easiest way to CHANGE data in one of the viewmodels?

I do not have a global JS object I can change in the console, and I have multiple elements with their own binding. I can of course create a button and a method on the viewmodel, but I want to play around with some values on the viewmodel to see the effect in the UI.

Preferably in Chrome.

回答1:

When developing a knockout website/application you often want to play around with different values to see how your UI reacts.

When your own code is neatly contained and not accessible via window, it can be difficult to gain access to your viewmodels.

Of course, you can modify your code to expose certain properties in window (e.g.: window.myObsProp = this.myObsProp). However, this requires you to edit your code and can be quite annoying when working with lists of viewmodels.

Therefore, a quick alternative is to use knockout's dataFor and contextFor utility functions.1

Using ko.dataFor or ko.contextFor you can return the binding context for a specific part of the DOM. ko.dataFor(element) is a shorthand for ko.contextFor(element).$data.

To quickly gain access to an element, most browsers expose a $0 global variable that contains the last inspected element. You can therefore retrieve your viewmodel using:

  1. Right mouse button -> inspect element
  2. In console: var vm = ko.dataFor($0)

To retrieve properties and edit them:

  1. get: vm.myObsProp()
  2. set: vm.myObsProp("some new value")

An example on knockout's hello world example

1. This does require you to expose ko in the global scope (window).



回答2:

Normally you would apply the bindings in a manner similar to this:

 ko.applyBindings(new Model());

But then the reference to the model is not available to you later on. Instead, if you keep a copy of the reference variable generated by new Model() you can change the observables within it, or check their values for debugging. Here's the pattern I employ when I need my model accessible to external code.

var vm = new Model();
ko.applyBindings(vm);

Now, if you wanted you could check the values in vm or update the observables if you wish. See the example below.

var Model= function() {
  var self = this;
  
  self.test = ko.observable("Initial Value");
}

var vm = new Model();
ko.applyBindings(vm);

setInterval(function() {
  vm.test("Value updated from external code!");
  
  setTimeout(function() {
    vm.test("New Value from external code!");
  }, 1000)
}, 2000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<input type="text" data-bind="textInput: test" />
<br/>
<span data-bind="text: test"></span>

Note: This might not be fully safe given that your vm is accessible under window object. So you might want to change it before deploying on production.



标签: knockout.js