I am trying to create dynamically generated variables based on another variable, such as:
var limit = 2;
$scope.blank_item = [];
$scope.create_vars = function(limit){
for(i=0; i<limit; i++){
eval('var item' + i) = $scope.blank_item;
};
};
And this should give me 3 new variables like below:
var item0 = [];
var item1 = [];
var item2 = [];
However, when I try to do this, I get the following error message:
ReferenceError: Invalid left-hand side in assignment
Is there something fundamentally wrong with my logic?
This has nothing to do with Angular. The value passed to eval() has to be one or more statements, not part of a statement. And you certainly can't pass part of a statement to eval() and then assign a value to it.
Even you could do that, it would just be creating temporary variables that disappeared as soon as your function finished executing.
Ditch the eval() and use an array:
var limit = 2;
var items = [];
$scope.blank_item = [];
$scope.create_vars = function(limit){
for(i=0; i<limit; i++){
items[i] = [];
};
};
Related
So I want to code faster by making array of all button that I have, and also make array of function which index numbers are connected to the array of each buttons.
For example, buttons[0], handler events for hover is button_over_funcs[0] and for out is button_out_funcs[0].
To make it clearer (since english is not my first language), take a look at my code:
var buttons:Array = [playbtn, tutorialbtn];
var button_over_funcs:Array = new Array();
var button_out_funcs:Array = new Array();
var i = 0;
for each(var j in buttons){
j.buttonMode = true;
button_over_funcs.push(function(e:MouseEvent){
j.gotoAndPlay("hover");
});
button_out_funcs.push(function(e:MouseEvent){
j.gotoAndPlay("out");
});
j.addEventListener(MouseEvent.ROLL_OVER, button_over_funcs[i]);
j.addEventListener(MouseEvent.ROLL_OUT, button_out_funcs[i]);
i++;
}
but the j will always refer to tutorialbtn, regardless which button I hover/out. I tried for-in as well
var buttons:Array = [playbtn, tutorialbtn];
var button_over_funcs:Array = new Array();
var button_out_funcs:Array = new Array();
for(var j in buttons){
buttons[j].buttonMode = true;
button_over_funcs.push(function(e:MouseEvent){
buttons[j].gotoAndPlay("hover");
});
button_out_funcs.push(function(e:MouseEvent){
buttons[j].gotoAndPlay("out");
});
buttons[j].addEventListener(MouseEvent.ROLL_OVER, button_over_funcs[j]);
buttons[j].addEventListener(MouseEvent.ROLL_OUT, button_out_funcs[j]);
}
Both seems the same. It seems like actionscript always refers to the last value of j instead of assigning it. Do you have any idea on how to make this as I expected? Is it impossible to make this quicker and not assigning the button to do same exact stuff?
There's no point in reinventing the wheel. Use SimpleButton and be done with it.
In general: a class is the way to go when you want to define behaviour that several objects have in common.
So I found the way by myself. If you found same problem as me, you can take a look.
var buttons:Array = [playbtn, tutorialbtn];
var button_over_funcs:Array = new Array();
var button_out_funcs:Array = new Array();
function addOver(ob){
button_over_funcs.push(function(e:MouseEvent){
ob.gotoAndPlay("hover");
});
}
function addOut(ob){
button_out_funcs.push(function(e:MouseEvent){
ob.gotoAndPlay("out");
});
}
function addEvent(ob){
addOver(ob);
addOut(ob);
}
for each(var j in buttons){
addEvent(j)
}
for(var i = 0; i<= buttons.length - 1; i++){
buttons[i].buttonMode = true;
buttons[i].addEventListener(MouseEvent.ROLL_OVER, button_over_funcs[i]);
buttons[i].addEventListener(MouseEvent.ROLL_OUT, button_out_funcs[i]);
}
What is the best effective way to collect data from a table using protractor.
I collecting the data shown in the code below and it is taking 20-30 seconds for 10 rows.
The buildStr counter is for creating a object for every row, 8 is the number of columns.
row = {};
gridRows = [];
element.all(by.css('#contenttableGrid div[role="gridcell"] div')).each(function(element){
element.getText().then(function(text){
row[headerName[buildStr]] = text;
buildStr++;
if(buildStr === 8){
buildStr = 0;
gridRows[rowCounter] = row;
rowCounter++;
row = {};
}
});
});
One way to speed it up that I see is to extract all the data right on the page by injecting script on it. It could be done with the help of browser.executeScript() (docs). In your sample Protractor has to make a request to the browser any time you call getText(), nubmer of calls it makes = number of cells in your table. But using browser.executeScript() it will make one call and do all the stuff in the browser, which can be really fast. Then you can simply return this data back to a test spec and use it via Promises.
var headerName = {};
// I assume that this variable holds names for headers
// you can pass data from test spec to injected script as arguments (below)
// promise will be resolved with the value you return from `executeScript`
var promise = browser.executeScript(function (headerName) {
// all the stuff inside this function happens on your page under test
// it is not a Protractor environment
var buildStr = 0;
var rowCounter = 0;
var row = {};
var gridRows = [];
var cells = document.querySelectorAll('#contenttableGrid div[role="gridcell"] div');
for (var i = 0, l = cells.length; i < l; i++) {
var text = cells[i].textContent;
// `headerName` object is passed as an argument from test spec
row[headerName[buildStr]] = text;
buildStr++;
if (buildStr === 8) {
buildStr = 0;
gridRows[rowCounter] = row;
rowCounter++;
row = {};
}
}
// return all collected data back to test spec
return gridRows;
}, headerName); // pass helper object from test spec to injectable function
promise.then(function (gridData) {
console.log(gridData); // result of computations
});
Make sure to read docs for browser.executeScript() if you want to use it, because it has a lot of specific moments.
Though coding, I must make many copies of the same MovieClip to be placed on the stage, each to be manipulated code-wise on its own
For instance, I have a MovieClip named MC and I wish to have 99 copies of ít loaded onto the stage, each in a different x coordinate. What should I do?
I think on doing this:
Step 1: in the library, turning MC into a class
Step 2: placing the following code in the scene's script
var MyArray:Array = new Array
for (var i:int = 0; i<99;i++)
{
var MCInstance:MC = new MC
MC Instance = MyArray[i]
MovieClip.(MyArray[i]).x = i*30
}
Would that make sense?
That's probably the right idea, your syntax is just a little off. Try this:
var myArray:Array = [];
for (var i:int = 0; i < 99;i++)
{
var mc:MC = new MC();
myArray[i] = mc;
mc.x = i * 30
}
AS3 style conventions: use lowerCamelCase for variable names, don't omit constructor parens even though they are optional, and create arrays using literals (source).
You could push each MovieClip to an Array after adding it to the Stage.
var myArray = [];
for(var i:int = 0; i < 99; i++)
{
var myMc:MC = new MC();
addChild(myMc);
myMc.x = myMc.width * i + 2;
myMc.y = 10;
myArray.push(myMc);
}
trace (suallar); - is written 2 times
1st time - HERE IT SHOWS ALL THE ELEMENTS OF THE ARRAY suallar
2nd time - BUT HERE THIS ARRAY SEEMS TO BE EMPTY, EVEN THOUGH I DIDN'T MANIPULATE WITH IT OR MAKE IT EQUAL TO ANYTHING I MANIPULATE WITH IN BETWEEN
var suallar:Array = new Array();
var i:int;
var cavablar:Array=new Array();
suallar.push(["sual1", "duz1", "sehv11", "sevh12", "sevh13","sevh14"]);
suallar.push(["sual2", "duz2", "sehv21", "sevh22","sevh23","sevh24" ]);
suallar.push(["sual3", "duz3", "sehv31", "sevh32","sevh33","sevh34"]);
suallar.push(["sual4", "duz4", "sehv41", "sevh42","sevh43","sevh44"]);
suallar.push(["sual5", "duz5", "sehv51", "sevh52","sevh53","sevh54"]);
var cavablar_temp:Array = suallar.concat();
for (i=0; i<suallar.length; i++){
cavablar_temp[i].shift();
}
trace (suallar);
for (i=0; i<suallar.length;i++){
var number_array:Array = cavablar_temp[i];
var final_array:Array = [];
var count_selected:int = 5;
for (var u = 0; u < count_selected; u++)
{
if (number_array.length == 0)
{
break;
}
else
{
final_array.push(number_array.splice(Math.floor(Math.random() * number_array.length), 1)[0]);
}
}
cavablar.push(final_array);}
trace(cavablar.join("\n"));
trace (suallar);
As per the Array.splice() documentation:
Adds elements to and removes elements from an array. This method modifies the array without making a copy.
When you do number_array.splice() in the middle of your loop, you're modifying the original arrays you pushed to suallar.
Take a look at Array.slice(), which returns a new array without modifying the original.
I'm pretty sure eval doesn't work this way, but it gets the idea across. I'm trying to dynamically create global variables; here's my code:
var ti_arr:Array = new Array;
_global.a = new Object;
for (var t=0; t<group_count-1; t++) {
numOfItems = group_nodes[t].childNodes.length;
ti_arr = "tab_info" add t;
// <-- I want to define a global array with the name held in ti_arr here
for (var i=0; i<numOfItems; i++) {
eval(ti_arr)[i].a.name = tempNode.attributes.name; //<-- or give the array global scope here
eval(ti_arr)[i].a.value = tempNode.attributes.value;
}
}
I need: tab_info1.a.name to have global scope.
I've been out of the actionscript loop for a while:
eval is bad.. brackets are good.
http://www.kirupa.com/forum/showthread.php?t=259717
It's explained simply here, not sure why so much searching on eval() didn't net me this sooner.
for (var i=0;i<3;i++) {
ti_arr = "new_array";
_global[ti_arr] = new Array
_global[ti_arr][i] = new Object
_global[ti_arr][i].name = tempnode.name
}