如何将多个功能节点全局存储在一个节点中, 并从任何需要的地方调用它作为可重用的函数? 是这样的吗?但是如何存储多个功能?
答案 0 :(得分:2)
我不完全确定这就是您要问的问题,但是我找到了一种方法来定义节点中的“全局”函数并从任何其他函数节点调用它们的完整集合。我将其称为自定义函数库。
它需要一个小技巧才能工作,但效果很好。
在第一个函数节点“define global_functions”中,您需要定义您的自定义函数。在任何需要您的库的节点之前,它至少需要调用一次:
var global_functions = {
load_global_functions: function(){
test1 = function(){
return "Test 1!";
}
test2 = function(){
return "Test 2!";
}
return this;
}
};
flow.set("global_functions", global_functions);
当然,如果您希望在所有流中共享功能,您可以使用全局上下文而不是流上下文。
在任何需要库的函数节点中,您只需要在使用任何自定义函数之前加载它:
// Load global functions
eval("lgf="+String(flow.get("global_functions").load_global_functions)+";lgf();");
// Run a custom function. Send the result to debug sidebar
node.warn(test1());
您可以在上面屏幕截图的调试侧栏中看到结果。
这是我的肮脏伎俩:由于某种原因,您不能简单地运行 flow.get("global_functions").load_global_functions();
,所以我设法使用了 eval,这一次证明是一个不错的解决方法。如果你能找到更好的方法,欢迎分享。
这里有完整的工作示例:
[{"id":"7aa9f6da.a3eeb8","type":"tab","label":"Global functions","disabled":false,"info":""},{"id":"8c828716.143678","type":"inject","z":"7aa9f6da.a3eeb8","name":"manual","props":[{"p":"payload","v":"","vt":"date"},{"p":"topic","v":"","vt":"string"}],"repeat":"","crontab":"","once":false,"onceDelay":"3","topic":"","payload":"","payloadType":"date","x":110,"y":40,"wires":[["b7263482.6356b8"]]},{"id":"b7263482.6356b8","type":"function","z":"7aa9f6da.a3eeb8","name":"define global_functions","func":"var global_functions = {\n\tload_global_functions: function(){\n\n\t\ttest1 = function(){\n\t\t\treturn \"Test 1!\";\n\t\t}\n\n\t\ttest2 = function(){\n\t\t\treturn \"Test 2!\";\n\t\t}\n\t\t\n \treturn this;\n\t}\n};\nflow.set(\"global_functions\", global_functions);\n","outputs":0,"noerr":0,"initialize":"","finalize":"","x":300,"y":40,"wires":[]},{"id":"ab941f1f.f5ac9","type":"inject","z":"7aa9f6da.a3eeb8","name":"manual","props":[{"p":"payload","v":"","vt":"date"},{"p":"topic","v":"","vt":"string"}],"repeat":"","crontab":"","once":false,"onceDelay":"3","topic":"","payload":"","payloadType":"date","x":110,"y":100,"wires":[["88f03f79.ac9d4"]]},{"id":"88f03f79.ac9d4","type":"function","z":"7aa9f6da.a3eeb8","name":"call test1()","func":"// Load global functions\n//flow.get(\"global_functions\").load_global_functions();\neval(\"lgf=\"+String(flow.get(\"global_functions\").load_global_functions)+\";lgf();\");\n\nnode.warn(test1());","outputs":1,"noerr":0,"initialize":"","finalize":"","x":270,"y":100,"wires":[[]]}]
答案 1 :(得分:1)
您可以使用子流来实现此目的。只需将一个功能节点放在子流中,并在需要的地方使用子流程。
或者,您可以使用settings.js
文件的全局变量部分来存储函数。然后,您可以通过将其分配给函数节点中的局部变量,在任何函数节点中访问它。如果考虑这个选项,您可能希望创建一个Node.js模块,因为这就是Node.js的工作方式。
最后,如果代码足够复杂以保证它,您可以考虑创建自定义节点。
答案 2 :(得分:0)
我的问题是需要一个js函数库,在很多node-red函数节点,很多大流中复用。 复制/粘贴不是解决方案 - 这是维护噩梦。
I found 一种使用存储在 JSON 字符串中的函数的方法。为此,我使用了存储在 global.myfunctions
节点中的 node-red-contrib-config
:现在它是一个真正的 'JSON object' 在面向对象的意义上,具有属性(一些其他常量)和方法.这个解决方案并不完美,也不快,需要在任何节点中同时调用myfunctions
和下面的函数(_callJSONMethod
),这些方法不能相互调用......但它有效!.< /p>
global.myfunctions
中的示例(node-red-contrib-config)(注意:全部在一行中)
{
"_getHello":"function(friend){return(\"Hi \"+friend);}"
}
如何在“函数”节点中使用它:
// local function requred to access `myfunctions`:
function _callJSONMethod(obj, fname, a, b, c, d) {
var wrap = s => "{ return " + obj[fname] + " };" // return the block having function expression
var func = new Function(wrap(obj[fname])); // ignore the node-red ⚠ warning
return func.call(null).call(obj, a, b, c, d); // invoke the function using arguments
}
var myfunctions = global.get("myfunctions");
.......
var message = _callJSONMethod(myfunctions, "_getHello", "George");
.......
这个策略解决了很多问题,主要是代码只有一个版本!其他优势:
notePad++
可以帮助您)