i want ArrayList forEach in {N}
how to? help us! plz.
Code for Java
public boolean OnPressEvent(ArrayList<MarkerItem> markers){
// in code
}
Code for {N}
onPressEvent: function(markers: MarkerItem[]) {
// in code (for android)
console.log("length", markers.length) // = undefined
console.log("length", markers.size()) // = 0~n (integer)
// i want run below codes.
markers.forEach(function(marker){
// marker editing....
});
}
The easiest way is:
onPressEvent: function(markers: MarkerItem[]) {
var size = markers.size();
for (var i=0;i<size;i++) {
var aMarker = markers.get(i);
// Do whatever I need to do with this item
}
});
Related
I'm trying to add a simple drop down control above a list such that I can sort it by "created" or "title".
The list template is called posts_list.html. In it's helper .js file I have:
posts: function () {
var sortCriteria = Session.get("sortCriteria") || {};
return Posts.find({},{sort: {sortCriteria: 1}});
}
Then, I have abstracted the list into another template. From here I have the following click event tracker in the helper.js
"click": function () {
// console.log(document.activeElement.id);
Session.set("sortCriteria", document.activeElement.id);
// Router.go('history');
Router.render('profile');
}
Here I can confirm that the right Sort criteria is written to the session. However, I can't make the page refresh. The collection on the visible page never re-sorts.
Frustrating. Any thoughts?
Thanks!
You can't use variables as keys in an object literal. Give this a try:
posts: function() {
var sortCriteria = Session.get('sortCriteria');
var options = {};
if (sortCriteria) {
options.sort = {};
options.sort[sortCriteria] = 1;
}
return Posts.find({}, options);
}
Also see the "Variables as keys" section of common mistakes.
thanks so much for that. Note I've left commented out code below to show what I pulled out. If I required a truly dynamic option, versus the simply binary below, I would have stuck w/ the "var options" approach. What I ended up going with was:
Template.postList.helpers({
posts: function () {
//var options = {};
if (Session.get("post-list-sort")) {
/*options.sort = {};
if (Session.get("post-list-sort") == "Asc") {
options.sort['created'] = 1;
} else {
options.sort['created'] = -1;
}*/
//return hunts.find({}, options);}
console.log(Session.get("hunt-list-sort"));
if (Session.get("hunt-list-sort") == "Asc") {
return Hunts.find({}, {sort: {title: 1}});
}
else {
return Hunts.find({}, {sort: {title: -1}});
};
}
}
});
Let's say I have three Views. AppView, MenuView and StripView. MenuView contains multiple StripViews and AppView contains one MenuView. How can I trigger event from StripView and listen on that event on AppView.
EDIT
Let's say I want to click on ImageSurface on StripView and reigster that event on AppView, and then do some transitionig.
MY SOLUTION
Everything is based on Timbre app, created in Famou.us Starter Kit Reference Tutorials
// StripView.js (_setListeners() is called in StripView constructor and bodySurface is defined in code)
function _setListeners() {
var eventScope = this._eventOutput;
this.backgroundSurface.on('click',function(){
eventScope.emit('test', { somedata:'some value'} );
}.bind(this));
}
// MenuView.js (_createStripViews() is called in MenuView constructor)
function _createStripViews() {
this.stripModifiers = [];
var yOffset = this.options.topOffset;
for (var i = 0; i < this.options.stripData.length; i++) {
var stripView = new StripView({
iconUrl: this.options.stripData[i].iconUrl,
title: this.options.stripData[i].title
});
var stripModifier = new StateModifier({
transform: Transform.translate(0, yOffset, 0)
});
this.stripModifiers.push(stripModifier);
this.add(stripModifier).add(stripView);
yOffset += this.options.stripOffset;
stripView.pipe(this._eventOutput);
}
}
//AppView.js (menuView is defined in code and _setListeners() is called in AppView constructor)
function _setListeners() {
this.menuView.on('test',function(){
console.log("IT WORKS");
}.bind(this));
}
You want to use Views built in handlers to achieve this. These are _eventInput and _eventOutput.. Here is an example using an ImageSurface in StripView and responding to a click in AppView..
Hope it helps!
// In StripView.js
var imageSurface = new ImageSurface();
imageSurface.on('click',function(){
this._eventOutput.trigger('image-click', { somedata:'some value'} );
}.bind(this));
// In AppView.js
var stripView = new StripView();
this.subscribe(stripView);
this._eventInput.on('image-click',function(data){
// Do Something
});
I'm trying to print out text when a user touches a sprite, however, even though I get no errors when building and running the code, the code refuses to printout the text and I cannot understand what I am doing wrong. Please help me understand why it does not print.
It prints the debug text when I touch the sprite, but not the GUI text with total.
This is the code:
#pragma strict
function Start () {
OnGUI();
}
function OnGUI(){
//var total = 0;
//GUI.Label( myRect, total.ToString() ); // Displays "10".
//GUI.Label( myRect, "" + bullets ); // Displays "10".
// GUI.Label(Rect(0,0,Screen.width,Screen.height),"Total:"+total);
}
//function Update () {
//}
var platform : RuntimePlatform = Application.platform;
function Update(){
if(platform == RuntimePlatform.Android || platform == RuntimePlatform.IPhonePlayer){
if(Input.touchCount > 0) {
if(Input.GetTouch(0).phase == TouchPhase.Began){
checkTouch(Input.GetTouch(0).position);
}
}
}else if(platform == RuntimePlatform.WindowsEditor){
if(Input.GetMouseButtonDown(0)) {
checkTouch(Input.mousePosition);
}
}
}
function checkTouch(pos){
var total = 0;
var wp : Vector3 = Camera.main.ScreenToWorldPoint(pos);
var touchPos : Vector2 = new Vector2(wp.x, wp.y);
var hit = Physics2D.OverlapPoint(touchPos);
if(hit){
GUI.Label(Rect(0,0,Screen.width,Screen.height),"Total:");
Debug.Log(hit.transform.gameObject.name);
hit.transform.gameObject.SendMessage('Clicked',0,SendMessageOptions.DontRequireReceiver);
//total = total +1;
}
}
You cannot put a gui item outside the OnGUI Method. You need to set a boolean to turn on the label.
Something along these lines.
OnGUI(){
if(labelbool)
GUI.Label ....
}
check(){
labelbool = true;
}
I read in this article http://www.adobe.com/devnet/flex/articles/flex-mobile-performance-checklist.html that I should not initialize a View's appearance in a creationComplete handler. Instead, I should change view's appearance in an overridden data setter.
The section in the article is:
Override the data setter instead of using bindings or initializing a View's appearance in a creationComplete handler
1-First, I would like to know if I got this right by doing the following:
//My code is loading a set of images and adding them in a View.
//On creationComplete of the View I am adding the images in case this is the first time
//the view is shown. In case the view has been already accessed I use the data:
protected function view1_creationCompleteHandler(event:FlexEvent):void
{
if(!data) //On first creation of the view I create the data object
{
data = new Object();
data.imageArray = new Array(); //set an array that will cache my images.
for(var i:int = 0; i<36;i++)
{
var img:Image = new Image();
img.source = 'assets/0'+i.toString()+'.png';
container.addElement(img);
(data.imageArray as Array).push(img);//Override the data for next time!
}
}
else//Next time use the save images
{
for(var ix:int = 0; ix<(data.imageArray as Array).length;ix++)
{
container.addElement((data.imageArray as Array)[ix]);
}
}
}
If I am doing this correctly, I would like to know which approach is best. The above one, or the next one I am going to show which uses the images contentLoader with caching and queuing enabled with a ContentCache:
protected function view1_creationCompleteHandler(event:FlexEvent):void
{
{
for(var i:int = 0; i<36;i++)
{
var img:Image = new Image();
img.contentLoader = ldr;
img.contentLoaderGrouping = 'gr1';
img.source = 'assets/0'+i.toString()+'.png';
container.addElement(img);
}
}
<fx:Declarations>
<s:ContentCache id="ldr" enableQueueing="true"
maxActiveRequests="1" maxCacheEntries="36"/>
</fx:Declarations>
Also if someone could tell me what is the contentLoaderGrouping for. I would be very grateful.
Thanks a lot!!!
PS:By the way both approaches work. The first approach is instant while the second approach shows the images beeing added in a very smooth way which actually gives a cool effect.
Neither. The point of the suggestion was to NOT alter the displaylist after creationComplete, which requires an additional update cycle. Instead you should inject the data property when you push your view on the stack, and initiate your changes in the setter. Using the ContentCache has nothing to do with it (and can sometimes cause additional overhead if not used correctly).
override public function set data(value:Object):void
{
super.data = value;
//this was poorly optimized, so I made it
//a little better...
var imageArray:Array = (value == null || value.imageArray == null)?
null : value.imageArray as Array;
if(imageArray == null) //On first creation of the view I create the data object
{
imageArray = new Array(36); //set an array that will cache my images.
for(var i:int = 0; i<36;i++)
{
var img:Image = new Image();
img.source = 'assets/0'+i.toString()+'.png';
container.addElement(img);
imageArray[i] = img;
}
super.data = {imageArray:imageArray}
}
else//Next time use the save images
{
var n:int = imageArray.length;
for (var j:int = 0; j < n; j++)
{
container.addElement(IVisualElement(imageArray[j]));
}
}
}
EDIT
I was mistaken about when the data property is set during the view life-cycle.
Here is how it works:
So you are correct that container would be null at that point. I was going to write up an example for you, but I'm having trouble figuring out what your end goal is here. Is there a specific reason you are storing the images on the data property? I think what you might actually want to do is this:
private var _data:Object = {cache: new ContentCache()};
protected function show_clickHandler(event:MouseEvent):void
{
this.navigator.pushView(views.MyView, _data);
}
And in the view...
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" title="MyView">
<fx:Script>
<![CDATA[
import spark.components.Image;
import spark.core.ContentCache;
override protected function createChildren():void
{
super.createChildren();
//you might want to do a sanity first check to make sure the
//data was passed in correctly...
var cache:ContentCache = ContentCache(this.data.cache);
for(var i:int = 0; i < 36; i++)
{
var img:Image = new Image();
img.contentLoader = cache;
img.source = 'assets/0' + i.toString() + '.png';
container.addElement(img);
}
}
]]>
</fx:Script>
<s:VGroup id="container" />
</s:View>
I am loading images for a game before the game begin. So the main function sends links of images to an image loading object. This is what happen in my image loading object when I do image.load(link) in my main :
public function charge(str:String, img_x:int, img_y:int, layer:Sprite):void
{
trace("load");
urlRequest = new URLRequest(str);
loaderArray[cptDemande] = new Loader();
loaderArray[cptDemande].contentLoaderInfo.addEventListener(Event.COMPLETE, loading_done);
loaderArray[cptDemande].load(urlRequest);
posX[cptDemande] = img_x;
posY[cptDemande] = img_y;
layerArray[cptDemande] = layer;
cptDemande++;
}
The parameters img_x:int, img_y:int and layer:Sprite are related to displaying the images afterward. I am using arrays to be able to add the images to the stage when the loading is all done.
The event listener fire this function :
public function loading_done(evt:Event):void
{
cptLoaded++;
evt.currentTarget.contentLoaderInfo.removeEventListener(Event.COMPLETE, loading_done);
if((cptDemande == cptLoaded) && (isDone == true))
{
afficher();
}
}
what I want is to be able to target the good loader to remove the event listener. What I am currently using(evt.currentTarget) doesn't work and generate an error code :
1069 Property data not found on flash.display.LoaderInfo and there is no default value
Tracing evt.currentTarget shows that currentTarget is the LoaderInfo property. Try updating your code as follows:
public function loading_done(evt:Event):void
{
cptLoaded++;
// Current target IS the contentLoaderInfo
evt.currentTarget.removeEventListener(Event.COMPLETE, loading_done);
//evt.currentTarget.contentLoaderInfo.removeEventListener(Event.COMPLETE, loading_done);
if((cptDemande == cptLoaded) && (isDone == true))
{
afficher();
}
}
Just a wee tip for you while I'm at it, you could make life a lot easier for yourself by storing all the properties of your images on an Object and then pushing these onto a single Array, rather than managing a separate Array for each property.
Something like this:
private var loadedImages:Array = new Array();
public function charge(str:String, img_x:int, img_y:int, layer:Sprite):void
{
var urlRequest:URLRequest = new URLRequest(str);
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loading_done);
loader.load(urlRequest);
var imageData:Object = { };
imageData.loader = loader;
imageData.posX = img_x;
imageData.posY = img_y;
imageData.layer = layer;
// Now we have a single Array with a separate element for
// each image representing all its properties
loadedImages.push(imageData);
cptDemande++;
}