Hi, I'd like to pass some parameters to my tap event, similar vanilla javascript in the browser.
Example:
<Button tap="doSomething(myObject)" />
Than, in javascript I would do, similar to:
exports.doSomething = function(myObject) {
console.log('param1', myObject.param1);
};
PS: I've tried args.view, but it get's me all the page, I also tried to add as a resource, but it happens before each tap.
Thanks
Hey @leocaseiro,
You can get the button instance from the tap event args like this:
exports.doSomething = function(arg) {
var button = args.object;
}
If you use same tap handler for multiple buttons you can define id similar to this example:
https://github.com/NativeScript/NativeScript/issues/1769#issuecomment-198268655
You can also put something in the global context if you want to access it across the entire app.
Hi @enchev,
Thank you for your quick answer.
I was expecting something more dynamic, otherwise I'll have to duplicate a lot of code...
Am I able to duplicated id? In my scenario, I have up to 4 phone numbers(I can't change that because of the legacy API), so I have a method to call the user and another one to send SMS, for example:
<Label text="{{Contact.phone1}}" />
<Button id="phone1" tap="sendSms" />
<Button id="phone1" tap="makeCall" />
<Label text="{{Contact.phone2}}" />
<Button text="sms" id="phone2" tap="sendSMS" />
<Button text="call" id="phone2" tap="makeCall" />
exports.doSomething = function(args) {
// use id
console.log('phone id: ', args.object.id);
var Contact = pageData.get('Contact');
callTo(Contact[args.object.id]);
}
Questions:
1) Can I use the same id more than once?
2) Any way to send the values to my function similar the Angular way?
Thanks a lot!
Hi @enchev,
I didn't know, but I realised that I'm able to create any attribute and the object will receive a attribute.
Doesn't work with bind values, but works, like so:
<Label text="{{Contact.phone1}}" />
<Button objNode="phone1" tap="sendSms" />
<Button objNode="phone1" tap="makeCall" />
<Label text="{{Contact.phone2}}" />
<Button text="sms" objNode="phone2" tap="sendSMS" />
<Button text="call" objNode="phone2" tap="makeCall" />
So I can use objNode as my attribute and get the global observable.
exports.doSomething = function(args) {
console.log('phone id: ', args.object.objNode);
var Contact = pageData.get('Contact');
callTo(Contact[args.object.objNode]);
}
Cheers
Hey @leocaseiro,
You can bind the tap event:
<Label text="{{ Contact.phone1 }}" />
<Button tap="{{ Contact.sendSms }}" />
<Button tap="{{ Contact.makeCall }}" />
You need to have functions to call or sms for the Contact object.
Expandos like in your last reply can work as well!
Hi @enchev,
I can bind, but I can't receive the Object values, can I? In that case, my solution would work the same way....
If your Contact object have everything needed to make a call (phone and function to call/sms the phone) you can use binding. Even if you have multiple phones per contact you can use for example Repeater to display all call/sms options. For example
<StackLayout>
<Label text="{Contact.name}" />
<Repeater items="{{ Contact.phones }}">
<Repeater.itemTemplate>
<Label text="{{ phone_number }}" />
<Button tap="{{ sendSms }}" />
<Button tap="{{ makeCall }}" />
</Repeater.itemTemplate>
</Repeater>
</StackLayout>
In this case your Contact object will be something like this:
class Contact {
phones: Array<Phone>;
}
class Phone {
phone_number: any;
call();
sendSms();
}
Hi @enchev, I'm aware of the repeaters which I use a lot, however, in this specific scenario, I have 4 string fields(phone1, phone2, phone3 and phone4) instead of Array<phone> as supposed to be.
Would you mind showing me an example of the Contacts with a function to send the sms? How do I'd know which button I press, then?
The far I went is:
Contacts.sendSMS = function(number) {
//how I get the right number here, than?
}
You can define the phone number as expando:
<Label text="{{ Contact.phone2 }}" />
<Button text="sms" phone="{{ Contact.phone2 }}" tap="sendSMS" />
Contacts.sendSMS = function(args) {
var phone = args.object.phone;
}
Also even if your original API is not flexible enough to use it in the way you want you can always wrap it in a new view-model with desired structure. That's the beauty of MVVM.
Perfect! That what exactly what I needed.
When using {N} with Angular, how would I get the GridLayout object for the below tap handler? Args.object does not seem to work. The GridLayout is a repeated element in a list view, so using template binding does not seem to be an option.
<GridLayout (tap)="doSomething()"></GridLayout>
In component file:
doSomething(){
// want to access the GridLayout instance here, so I can give it to the native script screenshot plugin
}
Hi @karaahmed, perhaps you should open an issue on the {N} angular repo.
However, I might be able to help you.
The same way you can access any DOM element with ElementRef with Angular 2, you can with {N} Angular.
First add an id with the hash(#), like #mygrid, and set as a @ViewChild.
Then, you can access on your Component Class, on the hook ngAfterViewInit:
import {AfterViewInit, Component, ElementRef, ViewChild} from '@angular/core';
@Component({
selector: 'my-component',
template: `<GridLayout #mygrid (tap)="doSomething()"></GridLayout>`
})
export class MyComponent implements AfterViewInit {
@ViewChild("mygrid") mygrid: ElementRef;
ngAfterViewInit() {
let myGrid = this.mygrid.nativeElement;
console.dump(myGrid); // I am a NativeScript Grid, with `.ios`, `.android` and so on...
}
}
PS: After that, you can use myGrid as a GridLayout with all properties.
I can't access the element that way because the GridView is in a ListView, so there are multiple instances of the GridView but only one that was tapped (that's the instance I want).
@karan1149 you can add a local variable #gridView to the specific view you want and then pass it as a parameter in your tap method
<GridLayout #gridView><Button (tap)="select(gridView)"></Button></GridView>
select(gridView) {
let grid = gridView;
grid.cssName = "newView";
}
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
You can define the phone number as expando:
Also even if your original API is not flexible enough to use it in the way you want you can always wrap it in a new view-model with desired structure. That's the beauty of MVVM.