@hiltex
tja leider ist das mit der doku sehr dürftig.
ich habe mich selbst du vorhanden code der widgets und auch von vis selbst durchgewühlt und viel debugged um zu verstehen wie ein paar sachen funktionieren.
leider ist vis sehr monolithis gebaut mit sehr großen funktionen (also mit vielen zeilen)
da macht es das debuggen schwer, weil man auch nicht immer so ganz versteht was da passiert.
vis mach auch nicht alles selbst, sondern behilft sich verschiedenen bibliotheken.
irgendwo steht was von vue, wird auch eingebunden, aber irgendwie nicht so richtig genutzt
um das mit dem binding von states in javascript zu verstehen muss man sich mit der bibliothek canJS 2.3.35 (leider sehr alt) auseinandersetzen.
https://v2.canjs.com/docs/index.html
auch ist in vis einige an automatismus und magie enthalten, die es normalen widget entwicklern leichter macht.
am beispiel des folgenden einfachen widgets
https://github.com/ioBroker/ioBroker.vis/blob/66dc4b7fcaf24164d2f4c3261af7df6d96a54a5d/www/widgets/basic.html#L2619
das ist ein widget/componenten template auf basis can.widget/can.Component
da gibt es ein bisschen rahmeninformation, das das widget in der auswahl angezeigt wird und den eigentlichen inhalt.
jedes attribut, das mit oid beginnt, wird von vis erkannt (aber nur beim start), wird dann über socketio beim server abonniert und erhält dann automatisch alle änderungen, bzw. wird einfach komplett neu gezeichnet.
wenn man das alles selber machen möchte, dann muss man verschiedene dinge selbst organisieren.
Ich habe mir diese Funktion gebaut, damit ich ein Array mit Datenpunkten abonnieren kann und über änderungen informiert werde
https://github.com/oweitman/ioBroker.openligadb/blob/68473c3be773ceb2368176c4261ca74ab1e5e21e/widgets/openligadb/js/openligadb.js#L1429
bindStates: function(elem,bound,change_callback) {
var $div = $(elem);
var boundstates = $div.data('bound');
if (boundstates) {
for (var i = 0; i < boundstates.bound.length; i++) {
vis.states.unbind(boundstates.bound[i], boundstates.change_callback);
}
}
$div.data('bound', null);
$div.data('bindHandler', null);
vis.conn.gettingStates = 0;
vis.conn.getStates(bound, function (error, states) {
vis.updateStates(states);
vis.conn.subscribe(bound);
for (var i=0;i<bound.length;i++) {
bound[i]=bound[i]+'.val';
vis.states.bind(bound[i] , change_callback);
}
$div.data('bound', {bound,change_callback});
$div.data('bindHandler', change_callback);
}.bind({change_callback}));
},
alle change_handler werden hier in einem html element gespeichert,
damit sie beim nächsten aufruf wieder deabonniert und neu aboniert werden können, ansonsten kann es leicht zu speicherüberlauf oder memory leaks kommen.
tricky ist, das es exakt die gleiche funktions objekt sein muss zum deabonnieren, sonst klappts nicht
auch muss man aufpassen, das eine Änderung am Datenpunkt nicht mit kaskadierenden De/Neu-Abonnierungen statt findet, sonst ebenfalls Speicherprobleme
Dann erst mal viel Spaß und wenn du Fragen hast, gerne