-1

I need to observe the variable myGlobalVar. I need to detect changes to it and display them.

function AppViewModel() {
    this.myVar = ko.observable(myGlobalVar);
}

// Activates knockout.js
ko.applyBindings(new AppViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<script>myGlobalVar = "Foo";</script>

<p>Test: <strong data-bind="text: myVar"></strong></p>

<script>
setTimeout(function() {
    myGlobalVar = "Bar";
    console.log("myVar set to 'Bar'. Proof:");
    console.log(myGlobalVar);
}, 1000);
</script>

In the example code above I initially set window.test to "Foo" and then after 3 seconds set it to "Bar", but the change is not getting detected.

Black
  • 18,150
  • 39
  • 158
  • 271
  • You can't observe changes to a variable. There are workarounds. You can create a [proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) object with all the watched variables as proxy's keys. And update the respective property in viewModel using the proxy set handler whenever each property is changed. [Listening for variable changes in JavaScript](https://stackoverflow.com/q/1759987) – adiga Oct 12 '20 at 16:46

2 Answers2

1

You could just update the observable instead of the global variable, to do so I made you an example how you can change it from everywhere using vm.myVar(value)

If you think this doesnt help, then think twice, you can make an interval function the sets the current global var like vm.myVar(myGlobalVar)

This is why "observables" exists hope it actually helps ;)

myGlobalVar = "Foo";
function AppViewModel() {
    this.myVar = ko.observable(myGlobalVar);
}

// Activates knockout.js (you see i´m assigning var vm)
var vm = new AppViewModel();
ko.applyBindings(vm);

setTimeout(function() {
    // edit the observable to update view
    vm.myVar("Bar") ;
    console.log("myVar set to 'Bar'. Proof:");
    console.log(vm.myVar());
}, 1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<script>myGlobalVar = "Foo";</script>

<p>Test: <strong data-bind="text: myVar"></strong></p>
john Smith
  • 17,409
  • 11
  • 76
  • 117
  • Thank you, I was able to solve it by making a modification https://stackoverflow.com/a/64332294/4684797 – Black Oct 13 '20 at 09:19
0

I was able to solve it thx to the answer of "john Smith", I changed it to add a change method. I could also just use an interval, but change is better in this context.

myGlobalVar = "Foo";
function AppViewModel() {
    this.myVar = ko.observable(myGlobalVar);
}

// Activates knockout.js (you see i´m assigning var vm)
var vm = new AppViewModel();
ko.applyBindings(vm);

setTimeout(function() {
    // edit the observable to update view
    vm.myVar("Bar") ;
    console.log("myVar set to 'Bar'. Proof:");
    console.log(vm.myVar());
}, 1000);



$("#globalVarField").change(function() {
    myGlobalVar = $(this).val();
    console.log("globalVarField changed to '"+ myGlobalVar + "'");
    
    vm.myVar(myGlobalVar);
});
.as-console-wrapper { max-height: 100px !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<script>myGlobalVar = "Foo";</script>

<p>Test: <strong data-bind="text: myVar"></strong></p>

Enter a value for myGlobalVar: <input type="text" id="globalVarField">
Black
  • 18,150
  • 39
  • 158
  • 271