I use Tabulator with Nuxtjs
Everything works fine but when I want to add an index, I have the error
[vuex] Do not mutate vuex store state outside mutation handlers.
Here is the code
watch: {
tableData:{
handler: function (newData) {
this.tabulator.replaceData(newData);
},
deep: true,
}
},
mounted(){
this.tabulator = new Tabulator(this.$refs.table, {
index: 'p',
data: this.data,
layout: "fitData",
columns: [
{title:"Num", field:"p"},
{title:"pn", field:"pn"},
{title:"par", field:"par"},
{title:"typec", field:"typec"},
{title:"ch", field:"ch"},
{title:"ar", field:"ar"},
],
rowClick:function(e, row){
$nuxt._router.push({ path: '/C/' + row.getIndex() })
},
});
// test to upade row
this.tabulator.updateData([{p:1, pn:"test"}, {p:3, prixnom:"test"}]);
}
Thanks !
Ok, I found
it is necessary to add
created () {
this.data = JSON.parse(JSON.stringify(this.rt));
},
Related
The meta data on my website is not updating when the route changes. The route itself has a watch on it which updates the view fine, but the metaInfo() from vue-meta is not keeping up. The <script> section of my code looks like this:
<script>
export default {
name: "Product",
watch: {
'$route.params.ProductID': {
deep: true,
immediate: true,
handler() {
this.getProduct(); // calls getProduct() on route change. Can I also call metaInfo() from here somehow?
}
}
},
metaInfo() {
return {
title: this.Product.ProductTitle,
meta: [
{
name: 'description', content: this.Product.ProductTitle
}
]
}
},
computed: {
Product() {
return this.$store.getters.getProduct
}
}, mounted() {
if (this.Product == null || !this.Product.length) {
this.getProduct();
}
}, methods: {
getProduct() {
return this.$store.dispatch('loadProduct', {ProductID: this.$route.params.ProductID})
}
}
}
</script>
What is happening is that when I change my route and go from /product/123 to /product/124, the metaInfo() still shows the meta data for /product/123. If I hit refresh, then the metaInfo() updates and shows the correct data for /product/124.
I need the watch to trigger an update of metaInfo() but don't know how to do it. I can't find this information in the docs anywhere. Please help?
For reactive, use variables outside return statements.
metaInfo() {
const title = this.Product.ProductTitle;
return {
title: title,
meta: [
{
name: 'description', content: title
}
]
}
}
https://vue-meta.nuxtjs.org/guide/caveats.html#reactive-variables-in-template-functions
I need to employ a filter function to implement a heuristic for selecting records. Simple field/value checks, alone, are inadequate for our purpose.
I'm trying to follow the examples for function filters, but for some reason, the "allowFunctions" flag keeps getting set to false.
I attempt to set the allowFunctions property to true in the storeConfig:
storeConfig: {
models: ['userstory', 'defect'],
allowFunctions: true,
filters: [{
// This did not work ...
property: 'Iteration.Name',
value: 'Sprint 3',
// Trying dynamic Filter Function. Update: Never called.
filterFn: function (item) {
console.log("Entered Filter Function!");
var iter = item.get("Iteration");
console.log("Iteration field: ", iter);
if (iter !== null && iter !== undefined) {
return (iter.name === "Sprint 3");
} else {
return false;
}
}
}]
},
After the grid view renders, I inspect it the store configuration and its filters:
listeners: {
afterrender: {
fn: function (_myVar, eOpts) {
console.log("Arg to afterrender: ", _myVar, " and ", eOpts);
var _myStore = _myVar.getStore();
console.log("Store filters: ", _myStore.filters);
}
}
},
What I find is that the allowFunctions property has been set back to false and I see that the filter function I specified never fired.
Console Screen Shot
So either I am setting allowFunctions to true in the wrong place, or something built into the Rally Grid View and its data store prohibits filter functions and flips the flag back to false.
OR there's a third option betraying how badly off my theory of operation is.
Oh, wise veterans, please advise.
Here's the entire Apps.js file:
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function () {
//Write app code here
console.log("Overall App Launch function entered");
//API Docs: https://help.rallydev.com/apps/2.1/doc/
}
});
Rally.onReady(function () {
Ext.define('BOA.AdoptedWork.MultiArtifactGrid', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function () {
console.log("onReady Launch function entered");
this.theGrid = {
xtype: 'rallygrid',
showPagingToolbar: true,
showRowActionsColumn: false,
editable: false,
columnCfgs: [
'FormattedID',
'Name',
'ScheduleState',
'Iteration',
'Release',
'PlanEstimate',
'TaskEstimateTotal',
'TaskActualTotal', // For some reason this does not display ?? :o( ??
'TaskRemainingTotal'
],
listeners: {
afterrender: {
fn: function (_myVar, eOpts) {
console.log("Arg to afterrender: ", _myVar, " and ", eOpts);
var _myStore = _myVar.getStore();
console.log("Store filters: ", _myStore.filters);
}
}
},
storeConfig: {
models: ['userstory', 'defect'],
allowFunctions: true,
filters: [{
// This did not work ...
property: 'Iteration.Name',
value: 'Sprint 3',
// Trying dynamic Filter Function. Update: Never called.
filterFn: function (item) {
console.log("Entered Filter Function!");
var iter = item.get("Iteration");
console.log("Iteration field: ", iter);
if (iter !== null && iter !== undefined) {
return (iter.name === "Sprint 3");
} else {
return false;
}
}
}]
},
context: this.getContext(),
scope: this
};
this.add(this.theGrid);
console.log("The Grid Object: ", this.theGrid);
}
});
Rally.launchApp('BOA.AdoptedWork.MultiArtifactGrid', {
name: 'Multi-type Grid'
});
});
This is a tricky one since you still want your server filter to apply and then you want to further filter the data down on the client side.
Check out this example here:
https://github.com/RallyCommunity/CustomChart/blob/master/Settings.js#L98
I think you can basically add a load listener to your store and then within that handler you can do a filterBy to further filter your results on the client side.
listeners: {
load: function(store) {
store.filterBy(function(record) {
//return true to include record in store data
});
}
}
I'm not familiar with allowFunctions, but in general remoteFilter: true/false is what controls whether the filtering is occurring server side or client side. remoteFilter: true + the load handler above gives you the best of both worlds.
I need to apply some computed filtering to the data store associated with a Rally Grid.
This code has a good bit of debugging "noise," but it shows that I'm trying to provide some filters at config time, and they're ignored, or seem to be since my filter function is not firing.
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function () {
//Write app code here
console.log("Overall App Launch function entered");
//API Docs: https://help.rallydev.com/apps/2.1/doc/
}
});
Rally.onReady(function () {
Ext.define('BOA.AdoptedWork.MultiArtifactGrid', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function () {
console.log("onReady Launch function entered");
this.theGrid = {
xtype: 'rallygrid',
showPagingToolbar: true,
showRowActionsColumn: false,
editable: false,
columnCfgs: [
'FormattedID',
'Name',
'ScheduleState',
'Iteration',
'Release',
'PlanEstimate',
'TaskEstimateTotal',
'TaskActualTotal', // For some reason this does not display ?? :o( ??
'TaskRemainingTotal'
],
listeners: {
afterrender: {
fn: function (_myVar, eOpts) {
console.log("Arg to afterrender: ", _myVar, " and ", eOpts);
console.log("Filters: ", _myVar.filters);
var _myStore = _myVar.getStore();
console.log("Store : ", _myStore);
console.log("Store filters: ", _myStore.filters);
}
}
},
filters: [{
// This did not work ...
property: 'ScheduleState',
operator: '==',
value: 'Defined',
// Trying dynamic Filter Function. Update: Never called.
filterFn: function (item) {
console.log("Entered Filter Function!");
var iter = item.get("Iteration");
console.log("Iteration field: ", iter);
if (iter !== null && iter !== undefined) {
return (iter.name === "Sprint 3");
} else {
return false;
}
}
}],
context: this.getContext(),
storeConfig: {
models: ['userstory', 'defect']
},
scope: this
};
this.add(this.theGrid);
console.log("The Grid Object: ", this.theGrid);
}
});
Rally.launchApp('BOA.AdoptedWork.MultiArtifactGrid', {
name: 'Multi-type Grid'
});
});
I have not coded in 12 years and never before in JavaScript. So, I'm getting my bearings.
Someone in the Rally Communities provided the answer and helpful feedback:
corkr03 said ...
#miguelfuerte a few things:
The "filters" configuration needs to be part of the storeConfig. In your code above it is part of the gridConfig.
storeConfig: {
filters: [{
property: "Iteration.Name",
value: "Sprint 3"
}]
}
Also, the filter for a property of "Iteration" will expect a reference to the Iteration reference. For that particular implementation, you will want to use the property: "Iteration.Name". There is good information about queries and using dot notation here: General Query Examples | CA Agile Central Help
I am trying to replicate the TODO MVC in VueJs.
(Please checkout this codepen : http://codepen.io/sankalpsingha/pen/gwymJg )
I have created a component called 'todo-list' with the following code :
Vue.component('todo-list',{
template: '#todo-list',
props: ['todo'],
data: function() {
return {
// Let us set up a isEditing Boolean so that we can know if the user
// will edit something and we need to change the state to reflect it.
isEditing: false,
}
},
methods: {
enableEditing: function() {
this.isEditing = true;
},
editTodo: function(todo) {
// todo.todo = todo.todo.trim();
this.isEditing = false;
},
removeTodo: function(todo) {
//this.todos.$remove(todo); // --> This part is not working?
}
}
});
However, I have the data defined in the app instance :
var app = new Vue({
el: '#todo-section',
data: {
newTodo: '',
todos: [
{
id: 1,
todo: 'Go to the grocery',
completed: false,
},
{
id: 2,
todo: 'See the movie',
completed: true,
},
{
id: 3,
todo: 'Jack Reacher : Tom Cruise',
completed: false,
}
]
},
methods: {
addTodo: function() {
// This will not allow any empty items to be added.
if(this.newTodo.trim() == '') {
return;
}
this.todos.push({
todo: this.newTodo.trim(),
completed: false,
});
this.newTodo = '';
}
}
});
I am not able to delete a single Todo from the list. My guess is that I have to send a emit message to the app instance and put up a listener there to delete the data from it? How do I delete the data?
When I tried to delete by clicking the x button in your codePen example, I see the error: this.$parent.todos.$remove is not a function.
I have not looked deeply into your code. But attempting to access parent component methods using this.$parent is not a good idea. Reason: a component can be used anywhere, and assuming that it will have a $parent with a particular property or method is risky.
As you suggested in your question, you need to use $emit from the child component to delete the data.
There was another similar question here few days ago, for which I created a jsFiddle: https://jsfiddle.net/mani04/4kyzkgLu/
The child component has some code like:
<button #click="$emit('delete-row')">Delete</button>
This sends out an event to parent component. Parent component can subscribe to that event using v-on as seen in that jsFiddle example.
Here is that other question for reference: Delete a Vue child component
It's preferable to use your methods (DeleteTodo, EditTodo...) in your parent.
var app = new Vue({
el: '#app',
data: {
newTodo: '',
todos: [{
id: 1,
title: 'Go to the grocery',
completed: false
}, {
id: 2,
title: 'See the movie',
completed: true
}, {
id: 3,
title: 'Jack Reacher : Tom Cruise',
completed: false
}]
},
methods: {
addTodo: function() {
this.todos.push({
todo: this.newTodo.trim(),
completed: false
});
this.newTodo = ''
},
deleteTodo: function(todo) {
this.todos = this.todos.filter(function(i) {
return i !== todo
})
}
}
});
<div id="app">
<ul>
<li v-for="todo in todos">{{ todo.title }}
<button #click.prevent="deleteTodo(todo)">
Delete
</button>
</li>
</ul>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>
I am using sencha to create a carousel which has multiple card panels. Each panel contains a list component that is attached to its own instance of a store.
All lists store instances call the same API to fetch the data but with different parameters.
Example:
Card 1, Has list 1 attached to Store 1 which calls mywebsite.com/api?node=1
Card 2, Has list 2 attached to Store 2 which calls mywebsite.com/api?node=2
Card 1 shows the right set of nodes retrieved from the API. But once i swipe to see card 2, both list 1 and list 2 show the exact same data although each one should have its own list od data.
Code:
Test.data.NodeStore = Ext.extend(Ext.data.Store, {
constructor : function(config) {
config = Ext.apply({
model: 'Test.models.Node',
autoLoad: false,
pageSize: 20,
proxy: {
type: 'scripttag',
url: Test.API.URL + '?action=getNodes',
extraParams: {
},
reader: {
type: 'json'
}
},
setSource: function(source) {
if(this.getProxy().extraParams.sourceID != source) {
this.getProxy().extraParams.sourceID = source;
}
}
}, config);
Test.data.NodeStore.superclass.constructor.call(this, config);
},
onDestroy : function(config) {
Test.data.NodeStore.superclass.onDestroy.apply(this, arguments);
}
});
Ext.reg('NodeStore', Test.data.NodeStore);
The list view:
Test.views.ListView = Ext.extend(Ext.Panel, {
sourceID: 0,
layout: {
type: 'vbox',
align: 'stretch'
},
items: [
{
xtype: 'list',
itemTpl : new Ext.XTemplate("<div class='node'>{title}</div>"),
store: Ext.create(Test.data.NodeStore, {}),
}
],
setSource: function(source) {
this.sourceID = source;
var store = this.items.get(0).getStore();
store.setSource(source);
store.load();
}
});
The main view which creates list views dynamically
Test.views.Viewer = Ext.extend(Ext.Carousel, {
indicator: false,
layout: 'card',
style: {
padding: '0 20px'
},
items: [
],
loadListView: function(listIndex) {
var currentRecord = Test.stores.ListStore.getAt(listIndex);
var newList = new Test.views.ListView();
newList.setSource(currentRecord.get('ID'));
this.add(newList);
this.doLayout();
},
initComponent: function() {
Test.views.Viewer.superclass.initComponent.apply(this, arguments);
loadListView(1);
loadListView(2);
}
});
This is really wierd... i am just wondering, is sencha assigning the exact same store, model, list component... don't know where to look
In the loadListView function, i had to create an object of store and assign it to the list dynamically rather than modifying existing store.
newList.items.get(0).store = Ext.create(Test.data.NodeStore, {});