I have been having a go at designing my own button and have managed a workable solution. However, I have a couple of questions.
The first question is that when using send(msg)
from within a scope$watch
function a new property templateScope
gets added. So, I was wondering what this property is supposed to be used for?
The second question is more of a request for help. I have shown the code below and what I want to know is 'is there any way of getting the HTML element (in this case a button) object into the <script>
without using an id
or some other method of having to know some identifier in the HTML?'. I am thinking of something along the lines of $element.target
but I have not so far found a way of accessing it.
<button id = "sonoffBtn02" class = "stdButton"
data-payload = '["OFF", "ON"]'
data-text = '["Off", "On"]'
data-device-name = "sonoffmini02"
data-device-type = "switch"
ng-class = "{true: 'redButton', false: 'greyButton'}[btnText == 'On']"
ng-click = "changeState()">
<text>{{btnText}}</text>
</button>
<script>
(function(scope) {
// Could also use [ angular.element(document.getElementById('sonoffBtn') ] or [ angular.element("#sonoffBtn") ]
// Introduction of a bit of JQuery to get the Element object
const el = angular.element(document.querySelector("#sonoffBtn02"));
const self = $(el);
// Data to use in the Scope
let btnData = {
text: self.data("text"),
payload: self.data("payload"),
};
let actionMsgIn = true; // Set to true to act on a change in msg
let topic = "ButtonState"; // Set topic if required
let btnState = 0; // Current toggle count. Max is length of text array
let device = {name: self.data("deviceName"), type: self.data("deviceType")};
// Data to return to HTML button
scope.btnText = btnData.text[btnState]; // Button text, also used as Class selector
/* Functions to use in the Scope */
// Toggle button state, update button text and create msg object
scope.changeState = function() {
toggle();
showChange();
this.msg = {};
this.msg.device = device;
this.msg.payload = btnData.payload[btnState];
this.msg.topic = topic;
};
// Triggered if the node receives a msg. Updates the button according to the payload received
scope.$watch('msg', function(msg) {
if (actionMsgIn) {
// Only change btnState if payload is valid (i.e. is found in btnData.payload)
if (btnData.payload.indexOf(msg.payload) !== -1) {
btnState = btnData.payload.indexOf(msg.payload);
}
showChange();
msg.device = device;
scope.send(msg);
}
});
// Toggle button state between 0 and length of btnData.text array
function toggle() {
btnState = (++btnState) % btnData.text.length;
};
// Update the scope variables to reflect back to the HTML
function showChange() {
scope.btnText = btnData.text[btnState];
};
})(scope);
</script>```