I have two qml files. I would connect a signal with javascript of the one qml file with a slot of the other qml file, but it seems not to work. The slot in the second file will not execute.
Here I connect the signal with the slot (in main.qml, GridLayout, onComplete):
var component = Qt.createComponent("Field.qml")
for (var i=0; i<30; i++) {
var object = component.createObject(mainGridLayout);
object.boardX = i % 5;
object.boardY = i / 5;
object.board = gameboard;
gameboard.fieldChanged.connect(object.fieldChange); //<-- Connect
}
Here I defined the signal (in main.qml):
Gameboard {
id: gameboard
signal fieldChanged(int x, int y, int val) //<-- Signal defined here
onBoardFieldChanged: { //<-- Works fine from C++
fieldChanged(x,y,value);
}
}
Here I defined the slot (in Field.qml):
function fieldChange(x, y, val){ //<-- Slot method
if (boardX==x && boardY == y) caption.text = val;
}
There are no errors in the console, but the slot did not execute. What did I do wrong? Thank you for your help.
Sorry I was a bit stupid. The code I posted is correct and works well. The problem was, that the signal was emitted before it was connected to the slot.
Related
I am doing some research on a running website, and the behavior of the code just surprises me.
They defined a function named '__jsload' and bind it to window.
window._jsload = function(hJ, hK) {
var i = d2.getModuleInfo(hJ);
i.status = d2.Request.LOADED;
if (hK !== "") {
d2.run(hJ, hK)
} else {
if (window.map) {
var e = new a6("ongetmodules_fail");
e.moduleName = hJ;
window.map.fire(e)
}
var T = document.createElement("script");
var hI = d2.MD5Mapping[hJ];
T.src = d2.Config.jsModPath + hJ + "_" + hI + ".js";
document.getElementsByTagName("head")[0].appendChild(T)
}
};
In the run function, there's only an eval(), it seems nothing is stored for future use.
run: function(T, hI) {
var hM = this.getModuleInfo(T);
var hP = this.Dependency[T];
if (hP) {
for (var hK = 0; hK < hP.length; hK++) {
var hL = this.getModuleInfo(hP[hK]);
if (hL.status !== this.Request.COMPLETED) {
hL.modsNeedToRun.push({
name: T,
code: hI
});
return
}
}
}
try {
eval(hI)
} catch (hN) {
return
}
hM.status = this.Request.COMPLETED;
for (var hK = 0, hJ = hM.callbacks.length; hK < hJ; hK++) {
hM.callbacks[hK]()
}
hM.callbacks.length = 0;
for (hK = 0; hK < hM.modsNeedToRun.length; hK++) {
var hO = hM.modsNeedToRun[hK];
this.run(hO.name, hO.code)
}
hM.modsNeedToRun.length = 0
},
Then all the module are written in the following manner.
/**/_jsload&&_jsload(
// this should be the module name
'glcommon',
// this should be the module content
'function aO(e,i)......'
)
I have a little experience in coding in python, so I thought those loaded modules will be special objects, and I can access functions defined in the module by just calling them.
import pandas as pd
pd.DataFrame()
And I searched some references on coding in javascript, they mentioned something like 'import/export' and maybe 'require'. After importing the module, I can call exported function just by calling the name.
// in sayHi.js
export function sayHi(user) {
alert(`Hello, ${user}!`);
}
// in main.js
import {sayHi} from './sayHi.js';
alert(sayHi); // function...
sayHi('John'); // Hello, John!
None of these things happens in that website I'm researching on. There's even no 'export' in the whole module text.
So, here rises my question.
Is it possible to call the function in a module in the web console? If it's not bound to the window object, will it still be possible?
We all know that currently a lot of web pages are dynamic, when a certain event happens, a certain function relate to it should be called. So, where are those functions saved? Are they still reachable during the web is running?
3.How can I debug modules like the above ones, when you can't get a pretty printed version of code and make some breakpoints? I tried to go step by step, but all the functions go into the text versioned module, and I can't make a breakpoint.
I'm trying to import an object into another JS file, and I keep getting this error, Uncaught ReferenceError: Cannot access 'stocks' before initialization. I've declared stocks, and I've imported it correctly, so I can't see what I did wrong. Any help is much appreciated. Thanks.
In the stocks file:
export const stocks = {
megaCorp: {
name: 'Mega Corporation',
value: decideStockValue(),
portIn: 0,
document: "mega"
},
lunaBake: {
name: "Luna Baking",
value: decideStockValue(),
portIn: 1,
document: "luna"
},
}
And in the user file :
import { stocks } from "./stocks.js";
export let user = {
money: 2000,
portfolio: [0, 0, 0, 0]
}
function getValue () {
let value = user.money;
let cannon = stocks.cannonRock.value * user.portfolio[0];
let alpha = stocks.alphaComp.value * user.portfolio[1];
let luna = stocks.lunaBake.value * user.portfolio[2];
let mega = stocks.megaCorp.value * user.portfolio[3];
value += cannon;
value += alpha;
value += luna;
value += mega;
return value;
}
user.value = getValue();
Again Looking at the code it seems syntactically fine, so this is not an answer but i rather want to share a snippet of code to see how it behaves.
The error you shared Uncaught ReferenceError: Cannot access 'variable_name' before initialization is thrown when a lexical variable was accessed before it was initialized ( what is known as a temporal dead zone error), however in the code you share there is nothing that should throw this error.
for example this code will throw this error
const x = 3
function a(){
console.log(x)
const x = 5;
}
a()
Assuming indeed that the error originated from the user file, then the following code might solve it. In the code u had getValue was a function expression that should be hoisted ( which again should be fine), but it could be that a bundler you are using is misbehaving.
import { stocks } from "./stocks.js";
const getValue = (stocks, money, portfolio) => {
let value = money;
let cannon = stocks.cannonRock.value * portfolio[0];
let alpha = stocks.alphaComp.value * portfolio[1];
let luna = stocks.lunaBake.value * portfolio[2];
let mega = stocks.megaCorp.value * portfolio[3];
value += cannon;
value += alpha;
value += luna;
value += mega;
return value;
};
const money = 2000;
const portfolio = [0, 0, 0, 0];
export const user = {
money,
portfolio,
value: getValue(stocks, money, portfolio),
};
After debugging for a little, I closed the server and opened it again. This time, it worked fine. I'm still not sure why the original error happened, but now it's working great. Thanks for everyone's help
This is a classic example of cycle overloading of certain dependancy (c) Sergei Vohmianin
The easiest thing you can do is to move that object into it's separate module just to omit cycle like app => method => app.
I was getting this error ReferenceError: Cannot access 'process' before initialization
when I attempted to do this:
require("dotenv-safe").config();
console.log(process.env);
const DATABASE_URI = process.env.DATABASE_URI;
Turns out, the problem was I was mistakenly declaring process further down in the same file like this:
const process = require("process");
This require was unnecessary since it's available in Node's global context. Deleting that line fixed the problem.
all. I have kind of a doozy of a problem, that could be solved really simply, if I just wanted to duplicate the code. I mean, really, it's a small part of a project that I'm doing just to see if I can, more than anything else, but it is bothering me since I've thought it up.
The Project
For fun, I've decided to take someone's ActionScript 3, text-based game engine and convert it to TypeScript and ultimately JavaScript using PixiJS.
The thing is, there are still 20213 errors to be fixed running tsc, so I could just leave this to a later date. But I was working on the Button class, which they defined as a subclass of MovieClip. That's fine; I just responded by reading up on PIXI buttons, and they seem fairly straightforward. Just, in the button's constructor, add something akin to the following lines:
export class Button extends PIXI.Sprite {
private _callback : Function;
private _height : number;
private _width : number;
public get callback() : Function { return this._callback; }
public set callback(fn : Function) {this._callback = fn; }
public get height() : number { return this._height; }
public set height(h : number) {this._height = h; }
public get width() : number {return this._width; }
public set width(w : number) {this._width = w; }
public constructor(width = 180, height = 90, callback: Function = null){
super(new PIXI.Texture(new PIXI.BaseTexture(GLOBAL.BTN_BACK, PIXI.SCALE_MODES.NEAREST)));
this.callback = callback;
this.width = width;
this.height = height;
this.buttonMode = true;
this.interactive = true;
this.anchor.set(0.5);
this.on('mousedown', this.callback)
.on('touchstart', this.callback);
}
}
That's a bit of a simplified version, and the version I did on Codepen uses a Container and a private _sprite field instead (as well as a ColorMatrixFilter that doesn't work too well on the black icons I picked out, but that's not really important for this question), but that's roughly the gist of how it's done.
The Problem
The problem is that, in the codepen, I'd like to do the following:
// assign `this.callback` to each of the following events:
let that = this;
['click','mousedown','touchstart'].map(evt => that.on(evt, that.callback});
with a simple call being passed in their constructors elsewhere:
for (let n = 0; n < 5; ++n){
btnArray.push(new Button(16, 16, () => console.info('You pushed button %d', n)));
}
but I'm not getting anything from them, even in the Chrome Console. I even logged that ColorMatrixFilter I mentioned earlier, to see if it was console.info that was wrong. Nope. So now, I'm confused on that. I was hoping to be able to just make a GLOBAL (a legacy static object from the AS source) key to iterate through for the events, but it looks like that's not happening.
The Questions
Is what I'm trying to do feasible, if odd? Is it blocked by a security feature (for which I'd be grateful)? If not, what am I doing wrong?
Should I even worry about setting all these different event handlers, or is just listening to click enough?
When an arrow function like your event map is executed the this context is not set, so any code that references this is going to get the current value, including any functions your map calls.
Replace your event map with the following:
['click','mousedown','touchstart'].map(function(evt) { that.on(evt, that.callback} } );
A demonstration:
function Named(x) {
this.name = x;
}
var foo = new Named("foo");
var bar = new Named("bar");
var showFunc = function show() {
// this is context dependant
console.log(this.name);
}
var showArrow;
// this is the window
showArrow = () => console.log(this.name);
var fooShowArrow;
(function() {
// this is foo
that = this;
fooShowArrow = () => console.log(that.name);
}).apply(foo);
var example = function(func) {
// For the demo, at this point, this will always be bar
func.apply(this, [ "arbitrary value" ]);
}
// explicitly set the current "this" to bar for the execution of these functions
example.apply(bar, [showFunc]); // works
example.apply(bar, [showArrow]); // fails, this is still the window
example.apply(bar, [fooShowArrow]); // fails, this is still foo
i have a problem using a class methods, after it was inserted into array. when i pull it back i can no longer use it methods.
and i know javascript does not have class, when i say class i mean object -or js equal.
suppose i have the following:
// a simple atomic class
function raw_msg(msg) {
this.msg = msg;
this.print = function () {
console.log(this.msg);
}
}
// and then i have this container for this "atomic" class
// which accept array of unknown object (known to me though..) = in_buffer
// i.e in_buffer is just an array of objects (one type of object)
function buffer(in_buffer) {
this.trans_buffer = null;
if (in_buffer!=null)
this.set_buffer (in_buffer);
this.set_buffer = function (buffer) {
this.trans_buffer = [];
var length = buffer.length,
row, new_raw_msg;
for(var x = 0; x < length; x++) {
row = buffer[x];
this.trans_buffer.push(new raw_msg(row));
}
console.log(this.trans_buffer);
}
this.use_some_raw_msg_method = function () {
var firstrow = this.trans_buffer[0];
firstrow.print(); // here is the problem!!!
//this here where i need help as it yield the error:
//Uncaught TypeError: Object #<Object> has no method 'print'
}
}
// this is how i use it, this code sits in a diffrent yet another class...
// this here im just building fake array
var buffer_in = [];
for (var x=0;x<10;x++)
buffer_in.push ("whatever" + x);
this.trans_buffer = new trans_helper(buffer_in);
this.trans_buffer.use_some_raw_msg_method (); // will yield the error as described
i hope this here, is clear, ask away if you need clarifications.
thanks for your help!
note to future readers - there is no problem in retrieving an object and using its methods.
You had several problems with your code.
Associative array does not have .push() method so the following line failed:
buffer_in.push ("whatever" + x);
To fix this just declare plain array:
var buffer_in = [];
You tried to create instance of function called trans_helper which does not exist. The name is buffer instead, so fix would be:
var trans_buffer = new buffer(buffer_in);
Last but not least, you tried to call function in the "class" when it still did not exist yet. JavaScript does not "compile" functions in advance, when inside function it will go line by line. So in this line in your code:
this.set_buffer (in_buffer);
There was still no function called "set_buffer" in your class. To fix this, place the function declaration above, on top.
Live test case.
this is my first post, but i'm excited to join this community. I have a question regarding JavaScript which I am completely stumped about.
I'm writing a JavaScript application which pulls data from a server using ajax and adds it to a chart. I'm using Jquery and Highcharts as the framework and then writing my own JavaScript 'wrapper' around Highcharts to produce the interface.
When the processData function get called back with the jSON response, it begins with i=1, even though i shouldn't even be initialized or even declared yet. Other variables are set as well. (I know this from using chrome developer tools to debug). This makes my loop not execute and none of my data gets added to the chart.
I don't know how much code to show, but these are the most relevant parts. I can add more if needed.
function getData(series, min, max, numpts) {
if (series === undefined) {
console.log("error on getData");
return;
}
var request = {};
request.series = series;
if (min !== undefined) {
request.start = min;
} //in seconds
if (max !== undefined) {
request.end = max;
}
if (numpts !== undefined) {
request.numpts = numpts;
}
$.getJSON('/data', request, processData);
return;
}
function processData(data) {
// handle the data after it comes back from an ajax request
var curSeries,
chartSeries,
curPoint;
for (var i = 0; i < data.length; i ++) {
curSeries = data[i];
chartSeries = chart.get(curSeries.name);
if (chartSeries === null) {
//alert("oops");
chart.addSeries(curSeries);
} else {
for (var j = 0; j < curSeries.data.length; j ++) {
curPoint = curSeries.data[j];
chartSeries.addPoint(curPoint, false);
}
}
}
chart.redraw();
}
These are both methods of a class I declared called graph.
Thanks if anyone has any ideas!
-Matt P
I'd console inspect your data object to make sure it's what you expect, as that loop should be working fine even if i is pre-declared: you're assigning 0 to it at the beginning of the loop, anyway.
The only reason I can think of that i would be defined and initialized before you defined and initialized it is if somewhere else in your codebase you don't initialize the i with the var keyword. Doing that would dump it into the global scope (the window object), making it available via closure to any and every function in your codebase.
If it's not in one of your files, it may be in the highcharts graphing library (in which case run very quickly away from said library).