Switching to a nested route is automatically running the last commit event from parent's store - vuejs2

Reproduction link
https://codesandbox.io/s/vue-template-c2gtb
Steps to reproduce
Open https://codesandbox.io/s/vue-template-c2gtb
Click on 'Go to Page with nested router' link
Click on 'commit event', it will show an alert box
Now change the nested route by clicking 'change nested route to reporting'
What is expected?
Route changed to reporting without showing the 'hello' alert box.
What is actually happening?
Its showing the 'hello' alert box again.

You should change your watcher to ignore cases when old value is the same as new value:
watch: {
event: {
handler(newVal,oldVal) {
if(oldVal === newVal) return; // <--- the important part
switch (this.event.id) {
case 'new_requirement': {
alert('hello');
break;
}
default:
}
},
},
},

Related

PrimeNg TabView with ConfirmDialog not working

I'm trying to use PrimeNg TabView component along with confirmDialog unsuccessfully
I am able to show this confirm dialog but it appears after user switch to target tab panel which is wrong.
<p-tabView (onChange)="handleChange($event)" [(activeIndex)]="index">...</p-tabView>
handleChange(e) {
this.confirmationService.confirm({
message: 'There are unsaved changes, do you want to proceed?',
accept: () => {
this.index = e.index;
},
reject:() =>{ }
});
}
Do you have an idea on how to prevent or allow tab change using confirm dialog ?
Thanks
there is no official way to prevent change to another tab by press on that tab , but 😅 there is a work around it first we need to prevent the tab change by tab click,
1️⃣ we need to set the header by ng-template or it called a custom header
template
<p-tabPanel >
<ng-template pTemplate="header">
<div (click)="handleChange($event,0)">
Godfather I
</div>
</ng-template>
.....
</p-tabPanel>
2️⃣ we bind a click event to the new header text and by using mouse event stopPropagation method we can prevent the change 👌,now we can control the change by confirm result but you need to pass the current tab index, that why I add another parameter to handleChange
component
handleChange(e:MouseEvent,tabIndex:number) {
e.stopPropagation();
if (this.index == tabIndex){
return;
}
// console.log(tabIndex)
this.confirmationService.confirm({
message: "There are unsaved changes, do you want to proceed?",
accept: () => {
this.index = tabIndex;
},
reject: () => {}
});
}
the if block if (this.index == tabIndex){return;} use to prevent showing the confirm dialog if we click on the same active tab again
demo 🚀🚀

Best way to clear a dialogs form after submit or close of the dialog

Below I show the parent vue which contains a dialog+form for adding a new record, in this case a user. When the form is cancelled, I would like input fields to be cleared, which in this case I am using v-model to tie those fields to a user template in the data method.
I would like to control this from the parent, as this is where calls to API are taking place, and if there is an error on save, i would like to retain the dialog form and present the error message, otherwise I would just clear the form on the dialog for button clicks.
Have looked at quite a few examples, and all seem to be wonky. Seems this should be simple enough but I have yet to figure out.
Parent vue
...
<AddUser
:visible="isAddDialogVisible"
:error="error"
v-on:onConfirmed="onAddUserConfirmed"
v-on:onCancelled="onAddUserCancelled"
/>
...
onAddClick: function() {
this.isAddDialogVisible = true;
}
...
onAddUserCancelled () {
this.isAddDialogVisible = false;
}
Dialog component
data() {
return {
user: {}
}
},
props: {
error: {},
visible: {
type: Boolean,
default: false,
}
},
...
onCancel() {
this.$emit("onCancelled");
}
Maybe the best and shortest way would be to do it with v-if:
<AddUser
v-if="isAddDialogVisible"
:visible="isAddDialogVisible"
:error="error"
v-on:onConfirmed="onAddUserConfirmed"
v-on:onCancelled="onAddUserCancelled"
/>
It will completely destroy dialog when false and re-render it when true.

Determine if opened as dialog in prompt

I am developing an aurelia app. I have a component (which is a full-page component and is navigable) and also in another page, I want to use this component as a prompt to let user choose from that page. So I have written the code below to open it as intended:
selectTaskFromTree(callbackOrSuccess, failure) {
const dialog = this.dialogService
.open({ viewModel: PLATFORM.moduleName('features/view/tree/tree'), model: {}, lock: false });
if (callbackOrSuccess) {
if (failure) {
dialog.whenClosed(response => {
if (!response.wasCancelled) {
callbackOrSuccess(response.output);
} else {
failure(response);
}
});
}
else{
dialog.whenClosed(callbackOrSuccess);
}
return;
}
else{
return dialog;
}
}
So the component Tree is now successfully loaded and shown. The problem is now how to determine if the TreeComponent is opened as a dialog or not.
The way I am thinking about is to pass an arbitrary param to it and if the param is true, the status is dialog and otherwise not dialog:
const dialog = this.dialogService
.open({ viewModel: PLATFORM.moduleName('features/view/tree/tree'), model: {isDialog: true}, lock: false });
But I think maybe there is also a better way to do this. For example to ask from DialogService if I am a dialog or not. So what are the other solutions and which one is better?
To determine whether or not you have an open (or active) dialog you can ask DialogService for the relevant fields:
this.dialogService.hasOpenDialog
this.dialogService.hasActiveDialog
Sadly, this cannot tell you which dialog is open. I would argue that your idea of passing a param to the model is an equally valid way of doing it.
I have thought about different solutions and I was seeking for keeping coupling low and preventing define of new param. So I wrote the below code where I want to know if this component is opened as a dialog or not:
attached() {
this._isDialog = Boolean(this.dialogController.settings);
}

making Ext.Action's text property dependent on another field's value

I have a grid within a window. The grid has 3 Actions: Edit, Delete and Disable.I was wondering if it is possible to make the text of the Disable Action (which is currently 'Disable/Enable') to be dependent on the Current Status of the record selected. So say the user selects a record whose Current Status is Enabled, then the action's text should be 'Disable'. If, however, the user selects a record whose status is Disabled, then the action's text should be 'Enable'. Is it possible to do this when using Action? Or do I need to use a button instead of Action?
I am assuming your action button is in a toolbar that is docked to the top of your grid panel. The only tricky thing is getting a reference to the grid (without hardcoding it). The grid's 'select' event only gives you a reference to the rowmodel used.
/* Set a action attribute on the Ext.Action so we can find it */
var action = new Ext.Action({
text: 'Do something',
handler: function(){
Ext.Msg.alert('Click', 'You did something.');
},
iconCls: 'do-something',
itemId: 'myAction',
action: 'myAction' // I don't like itemId's personally :)
});
/* In the Controller */
init: function() {
this.control({
'mygrid': {
select: this.onRecordSelect
}
});
},
onRecordSelect: function(rowModel, record) {
var grid = rowModel.views[0].ownerCt);
var action = grid.getDockedItems('toolbar[dock="top"]')[0].down('button[action="myAction"]');
var enabled = (record.get('CurrentStatus') == "Enabled");
action.setText(enabled ? 'Disable' : 'Enable');
action.setIconCls(enabled ? 'myDisableCls' : 'myEnableCls');
}
/* in SASS */
.myDisableCls{
background-image:url(#{$icon_path}/checkbox.png) !important;
}
.myEnableCls {
background-image:url(#{$icon_path}/checkbox_ticked.png) !important;
}
Good luck!
I solved the problem in another way. This is my code:
grid.getSelectionModel().on({
selectionchange: function(sm, selections) {
if (selections.length > 0) {
Edit.enable();
Delete.enable();
if(selections[0].data.CurrentStatus == "Disabled"){
Disable.setText("Enable");
Disable.enable();
}else{
Disable.setText("Disable");
Disable.enable();
}
} else {
Edit.disable();
Delete.disable();
Disable.disable();
}
}
});

Sencha Touch - event listener for NestedList back button?

Sencha Touch 1.1.1 --
Is there a way to set up a listener to listen for click events on the Back button of a NestedList? I can only find examples of how to set up for clicks on the 'body' or 'el' element. How would you be more specific and target the NestedList's back button?
Many Thanks
Code so far
MyTest.views.Justacard = Ext.extend(Ext.NestedList, {
title: "The Title",
...
listeners: {
click: {
element: 'el', // ANYTHING HERE TO TARGET THE BACK BUTTON?
fn: function(){
// do action
}
}
}
});
Ext.reg('justacard', MyTest.views.Justacard);
On a side note: because the NestedList component adds the back button automatically, there's no opportuity to configure it and add a handler (I think).
PS: adding the following code (below title: for example) allows me to respond to the Back button clicks - however, it also removes all the normal Back button functionality and the NestedList no longer slides back to the parent list.
onBackTap: function() {
alert('boo');
}
Turning into a proper 'lumpy carpet' scenario ; )
Try
MyTest.views.Justacard = Ext.extend(Ext.NestedList, {
title: "The Title",
...
listeners: {
back: function() {
alert('back?');
}
}
});
or
onBackTap: function() {
this.callParent(arguments);
alert('boo');
}
P.S. Sorry, I didn't test this (just looked at sources)