You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi there, I am working on a ListView that highlights the elements when the user taps on a specific item. I am trying to add a CSS style to make it looks like its selected but seems like its not adding the style. This is my HTML code:
@relez the thing is that in this case the Angular navigation event (via nsRouterLink) is triggered before the itemTap event. This causes the application to navigate to the second page before any changes in the CSS are applied. So the solution would be either to move the navigation in the code behind (after the changes in CSS classes e.g. via RouterExtension) or to apply the changes in the CSS earlier for example using the touch event.
Hi @NickIliev, thanks for the quick answer. I am not navigating anywhere when the user tap on the item (Label), I just want to simulate a multi-select ListView.
Using your workaround the touch event fires multiple times. Did you notice that?
@relez the Touch event is triggered multiple times as it has 4 different states (up, down, move and cancel) known as TouchAction. To trigger the change only on one specific action you could do the folllowing
onItemTouch(event:TouchGestureEventData) : void{letlb=<Label>event.object;switch(event.action){case"up":
console.log(" UP");// and for example, you could reset the style on up (or not depending on your UX requrments)// lb.className = "item item-content top-left-rounded top-right-rounded bot-left-rounded bot-right-rounded";break;case"down":
console.log(" DOWN");lb.className="item item-content top-left-rounded top-right-rounded bot-left-rounded bot-right-rounded item-selected";break;case"move":
console.log(" MOVE");break;case"cancel":
console.log(" CANCEL");break;default:
break;}}
Hi @NickIliev, thanks for the clarification. Unfortunately the css is not being applied in the view even with your suggestion only triggering in the DOWN event. I have updated the example at github https://github.com/relez/ns-angular-css.git so you can see what I am trying to do. The CSS rule I want to add/remove looks like this:
Also don't you think using the (itemTap)="onItemTap($event)" of the ListView its enough?, since it triggers only one time and I am able to get the label let lb = <Label>event.view; instance and play with it. Actually, I can change the text of the label using lb.text = "nativescript";, but CSS seems its not updating the view.
Can you take a quick look at it?
@relez thank you for providing the sample project. There are two things to notice - the way you are accessing your current View in the list view cell and the issue itself which seems that can be reproduced on iOS.
The first thing I want to notice is that you should access the unique Label and not the current list view cell view. When working with ListView we should consider that all cells are recycled and any changes applied to the current cell (via ItemEventData arguments) will be eventually reused and this would cause the side effect that the changes will be applied on reused cells (when the user scrolls). So the correct way to access and change a CSS style of any View would be while using a unique ID. (via the model in your case we can use the ID property of each item).
For example:
import{Component,OnInit}from"@angular/core";import{ObservableArray}from"tns-core-modules/data/observable-array/observable-array";import{Page}from"ui/page";import{ListView,ItemEventData}from"ui/list-view";import{Label}from"ui/label";import{TouchGestureEventData}from"ui/gestures";declareletUITableViewCellSelectionStyle: any;letlistview: ListView;
@Component({selector: "Home",moduleId: module.id,templateUrl: "./home.component.html"})exportclassHomeComponentimplementsOnInit{privateitems: Array<any>;constructor(private_page:Page){// Use the component constructor to inject providers.}ngOnInit(): void{// Init your component properties here.this.items=[{id: 1,Description: "Item 1"},{id: 2,Description: "Item 2"},{id: 3,Description: "Item 3"},{id: 4,Description: "Item 4"},{id: 5,Description: "Item 5"},{id: 6,Description: "Item 6"},{id: 7,Description: "Item 7"},{id: 8,Description: "Item 8"},{id: 9,Description: "Item 9"}];}onItemTap(args: ItemEventData){console.log("args.view: ",args.view);console.log("args.view.id: ",args.view.id);letlb=<Label>this._page.getViewById(args.view.id);console.log("lb: ",lb);lb.className="item-selected";// WORKAROUND: the bug is that we have to manually refresh the listview on iOSletlistview=args.objectasListView;listview.refresh();}}
The above approach is allowing us to change the style only for the specific Label and not for the label of the current cell (which will be reused and would cause when scrolling to apply the style on the newly reused cells and their labels).
The unexpected behaviour, which I am marking as a bug is that we need to explicitly call refresh for the changes to be rendered in the UI. This is happening only on iOS.
We're still seeing problems with cssClasses in nativescript-angular 7.0 and core 5.0: The class doesn't get applied dynamically when using add / delete. We're trying to apply a class from a directive.
Using .className works, but can potentially overwrite existing classes.
This is on Android though, so I'm guessing its a problem on both platforms.
Activity
NickIliev commentedon May 10, 2018
@relez the thing is that in this case the Angular navigation event (via
nsRouterLink) is triggered before theitemTapevent. This causes the application to navigate to the second page before any changes in the CSS are applied. So the solution would be either to move the navigation in the code behind (after the changes in CSS classes e.g. viaRouterExtension) or to apply the changes in the CSS earlier for example using thetouchevent.Example
and the HTML
relez commentedon May 10, 2018
Hi @NickIliev, thanks for the quick answer. I am not navigating anywhere when the user tap on the item (Label), I just want to simulate a multi-select ListView.
Using your workaround the touch event fires multiple times. Did you notice that?
Thanks!
NickIliev commentedon May 10, 2018
@relez you could try to change the CSS on a specific
TouchAction.relez commentedon May 10, 2018
Hey @NickIliev, take a look at this example you will see what I mean. I hope this example help you to understand what I am trying todo.
https://github.com/relez/ns-angular-css.git
NickIliev commentedon May 11, 2018
@relez the
Touchevent is triggered multiple times as it has 4 different states (up,down,moveandcancel) known asTouchAction. To trigger the change only on one specific action you could do the folllowingWhere
onItemTouchis thetouchevent callbackrelez commentedon May 11, 2018
Hi @NickIliev, thanks for the clarification. Unfortunately the css is not being applied in the view even with your suggestion only triggering in the DOWN event. I have updated the example at github https://github.com/relez/ns-angular-css.git so you can see what I am trying to do. The CSS rule I want to add/remove looks like this:
Also don't you think using the
(itemTap)="onItemTap($event)"of the ListView its enough?, since it triggers only one time and I am able to get the labellet lb = <Label>event.view;instance and play with it. Actually, I can change the text of the label usinglb.text = "nativescript";, but CSS seems its not updating the view.Can you take a quick look at it?
Thanks!
NickIliev commentedon May 15, 2018
@relez thank you for providing the sample project. There are two things to notice - the way you are accessing your current
Viewin the list view cell and the issue itself which seems that can be reproduced on iOS.The first thing I want to notice is that you should access the unique
Labeland not the current list view cell view. When working withListViewwe should consider that all cells are recycled and any changes applied to the current cell (viaItemEventDataarguments) will be eventually reused and this would cause the side effect that the changes will be applied on reused cells (when the user scrolls). So the correct way to access and change a CSS style of anyViewwould be while using a unique ID. (via the model in your case we can use the ID property of each item).For example:
and in the HTML
The above approach is allowing us to change the style only for the specific
Labeland not for the label of the current cell (which will be reused and would cause when scrolling to apply the style on the newly reused cells and their labels).The unexpected behaviour, which I am marking as a bug is that we need to explicitly call
refreshfor the changes to be rendered in the UI. This is happening only on iOS.NickIliev commentedon May 15, 2018
Test project demonstrating the above can be found here
relez commentedon May 15, 2018
Thanks @NickIliev, I will keep an eye on the updates.
2 remaining items
larssn commentedon Nov 16, 2018
We're still seeing problems with
cssClassesin nativescript-angular 7.0 and core 5.0: The class doesn't get applied dynamically when usingadd/delete. We're trying to apply a class from a directive.Using .className works, but can potentially overwrite existing classes.
This is on Android though, so I'm guessing its a problem on both platforms.