I'm new to ng2-smart-tables. I'm trying modify the example below from the GitHub page so that the check boxes don't disappear when moving from page to page.
import { Component } from '#angular/core';
#Component({
selector: 'basic-example-multi-select',
template: `
<ng2-smart-table [settings]="settings" [source]="data"></ng2-smart-table>
`,
})
export class BasicExampleMultiSelectComponent {
settings = {
selectMode: 'multi',
columns: {
id: {
title: 'ID',
},
name: {
title: 'Full Name',
},
username: {
title: 'User Name',
},
email: {
title: 'Email',
},
},
};
data = [
{
id: 1,
name: 'Leanne Graham',
username: 'Bret',
email: 'Sincere#april.biz',
},
{
id: 2,
name: 'Ervin Howell',
username: 'Antonette',
email: 'Shanna#melissa.tv',
},
{
id: 3,
name: 'Clementine Bauch',
username: 'Samantha',
email: 'Nathan#yesenia.net',
},
{
id: 4,
name: 'Patricia Lebsack',
username: 'Karianne',
email: 'Julianne.OConner#kory.org',
},
{
id: 5,
name: 'Chelsey Dietrich',
username: 'Kamren',
email: 'Lucio_Hettinger#annie.ca',
},
{
id: 6,
name: 'Mrs. Dennis Schulist',
username: 'Leopoldo_Corkery',
email: 'Karley_Dach#jasper.info',
},
{
id: 7,
name: 'Kurtis Weissnat',
username: 'Elwyn.Skiles',
email: 'Telly.Hoeger#billy.biz',
},
{
id: 8,
name: 'Nicholas Runolfsdottir V',
username: 'Maxime_Nienow',
email: 'Sherwood#rosamond.me',
},
{
id: 9,
name: 'Glenna Reichert',
username: 'Delphine',
email: 'Chaim_McDermott#dana.io',
},
{
id: 10,
name: 'Clementina DuBuque',
username: 'Moriah.Stanton',
email: 'Rey.Padberg#karina.biz',
},
{
id: 11,
name: 'Nicholas DuBuque',
username: 'Nicholas.Stanton',
email: 'Rey.Padberg#rosamond.biz',
},
];
}
This uses the selectMode : 'multi'option to show a column with check boxes. The check boxes do show, but every time I use the pagination links to go to another page, the selection is cleared. I'm trying to solve this problem because I have a problem on my project which is analogous to this.
I tried to find documentation on how to persist the selection across pages, but was not successful as only a limited amount of documentation is available. This seems like a feature that's common enough that there should be more information on this out there, but doesn't seem to be the case. Any help on this issue would be greatly appreciated.
I haven't used multi-select with ng2-smart-tables myself, but the documentation mentions
doEmit: boolean - emit event (to refresh the table) or not, default = true
I'm not sure if this will work, but you could try to set this to false.
Create a DataSource from your data and then modify the paginator settings:
source: LocalDataSource;
constructor() {
this.source = new LocalDataSource(this.data);
this.source.setPaging({ doEmit: false });
}
If this doesn't work, you might try adding event-listeners that collect the checked rows on check and re-select them on refresh (or init). Add event callbacks to the table...
<ng2-smart-table [settings]="settings" [source]="source" (rowSelect)="onRowSelect($event)" (userRowSelect)="onUserRowSelect($event)"></ng2-smart-table>
...log the events and see if you get any usable information from there.
onRowSelect(event) {
console.log(event);
}
onUserRowSelect(event) {
console.log(event);
}
If none of this helps, open a new issue on github and hope the developers know an easy way to fix this. :-)
And if that fails too, do what I did and switch to angular/material2. Their documentation sucks, but overall I think it's better than most components out there.
import { LocalDataSource } from 'ng2-smart-table';
settings = {
...
}
data = [
...
]
source: LocalDataSource;
constructor() {
this.source = new LocalDataSource(this.data);
this.source.setPaging(1,10,false);
}
If you want to maintain data along the live of a application, you must save this data in a "persistent way" and use the data saved in the ngOnInit.
In a component, I use ngOnDestroy and a dataService
#Component({
})
export class MyComponent implements OnInit,OnDestroy {}
variable1:number
variable2:number
contructor(private state:MyComponentData)
ngOnInit() {
let data=this.state.Data?data:null;
this.variable1=(data)?data.variable1;
this.variable2=(data)?data.variable2;
}
ngOnDestroy()
{
this.state.Data={
variable1:this.variable1,
variable2:this.variable2
}
}
The service is so easy as
#Injectable()
export class MyComponentData{
Data:any;
}
Related
I'm following this tutorial on the Apollo blog (here's my forked repo), and I've been going over this for a solid day, and still can't figure out why my resolvers aren't being used, so turning to help here. As near as I can tell, I've tried it exactly as the tutorial claims.
I was able to return data from mocks, so everything up to that point was working.
Here's the simple schema.js:
import { makeExecutableSchema, addMockFunctionsToSchema } from 'graphql-tools';
//import mocks from './mocks';
import { resolvers } from "./resolvers";
const typeDefs = `
type Author {
id: Int
firstName: String
lastName: String
posts: [Post]
}
type Post {
id: Int
title: String
text: String
views: Int
author: Author
}
type Query {
getAuthor(firstName: String, lastName: String): Author
allAuthors: [Author]
}
`;
const schema = makeExecutableSchema({ typeDefs, resolvers });
// addMockFunctionsToSchema({ schema, mocks, preserveResolvers: true});
export default schema;
And my resolvers.js file:
const resolvers = {
Query: {
getAuthor(_, args) {
console.log("Author resolved!");
return ({ id: 1, firstName: "Hello", lastName: "world" });
},
allAuthors: () => {
return [{ id: 1, firstName: "Hello", lastName: "world" }];
}
},
Author: {
posts: (author) => {
return [
{ id: 1, title: 'A post', text: 'Some text', views: 2 },
{ id: 2, title: 'A different post', text: 'Different text', views: 300 }
];
}
},
Post: {
author: (post) => {
return { id: 1, firstName: 'Hello', lastName: 'World' };
}
}
};
export default resolvers;
Given that I'm returning static objects, there's no need worry about syncronicity, so any ideas on why my query:
query {
getAuthor {
firstName
}
}
is returning null?
{
"data": {
"getAuthor": null
}
}
Change:
Query: {
getAuthor(_, args) {
console.log("Author resolved!");
return ({ id: 1, firstName: "Hello", lastName: "world" });
},
to:
Query: {
getAuthor(root, {_, args}) {
console.log("Author resolved!");
return ({ id: 1, firstName: "Hello", lastName: "world" });
},
root is not really well documented but you have to include it when you are doing queries on base schema types. You are trying to return an Author type which is an entry point into the GraphQL API because getAuthor is a root query, so therefore you must include root.
Check out https://www.howtographql.com/graphql-js/2-a-simple-query/. Read the section called:
The query resolution process
It explains the root object a little better.
I am trying to create a dictionary for each record returned in an API call.
my broken code:
import lazyLoading from './lazyLoading'
// get records from api call
created() {
axios.get('http://localhost:8080/api/tools/')
.then(response => {
this.json_data = response.data
console.log(this.json_error)
})
.catch(error => {
console.log(error);
})
export default {
name: 'test',
meta: {
icon: 'fa-android',
expanded: false
},
const children = [];
json_data.forEach(item => {
const dict = {
name: item.name,
path: item.path,
meta: {
label: item.label,
link: item.link,
},
component: lazyLoading('testitem/basic'),
}
children.push(dict);
});
}
desired result:
export default {
name: 'test',
meta: {
icon: 'fa-android',
expanded: false
},
children: [
{
name: 'test',
path: 'test',
meta: {
label: 'test',
link: 'test'
},
component: lazyLoading('test/basic')
},
{
name: 'test',
path: 'test',
meta: {
label: 'test',
link: 'test'
},
component: lazyLoading('test/Basic')
},
{
name: 'test',
path: 'test',
meta: {
label: 'test',
link: 'test'
},
component: lazyLoading('test/Basic')
}
]
(obviously 'test' would be replaced what is returned in the api). The main problem is I don't know how to dynamically create the dictionarys. I also have no idea how to view/troubleshoot my axios request. I assumed console.log would spit out the object into the chrome dev tools under console section but I don't see the object there. I'm completely new to javascript so maybe I'm not looking in the correct spot.
Also I'm getting this error:
Module build failed: SyntaxError: 'import' and 'export' may only appear at the top level
So where do I put my api request if I cannot put it at the top?
Basically i've made proyxy-component which renders different components based on what the :type is and it works great. The point is that I create a schema of the form controls and a separate data object where the data from the form controls is stored. Everything is working good but i have a problem when formData object contains nested objects.
In my example test.test1
How can i make the v-model value dynamic which is generated based on what the string is.
My Compoennt
<proxy-component
v-for="(scheme, index) in personSchema.list"
:key="index"
:type="scheme.type"
:props="scheme.props"
v-model="formData[personSchema.prefix][scheme.model]"
v-validate="'required'"
data-vv-value-path="innerValue"
:data-vv-name="scheme.model"
:error-txt="errors.first(scheme.model)"
></proxy-component>
Data
data() {
return {
selectOptions,
formData: {
person: {
given_names: '',
surname: '',
sex: '',
title: '',
date_of_birth: '',
place_of_birth: '',
nationality: '',
country_of_residence: '',
acting_as: '',
test: {
test1: 'test',
},
},
},
personSchema: {
prefix: 'person',
list: [
{
model: 'given_names',
type: 'custom-input-component',
props: {
title: 'Name',
},
},
{
model: 'surname',
type: 'custom-input-componentt',
props: {
title: 'Surname',
},
},
{
model: 'test.test1',
type: 'custom-input-component',
props: {
title: 'test 1',
},
},
{
model: 'sex',
type: 'custom-select-component',
props: {
title: 'Sex',
options: selectOptions.SEX_TYPES,
trackBy: 'value',
label: 'name',
},
},
],
},
};
},
I would recomment you to write a vue-method (under the data section) that returns the object for v-model
v-model="resolveObject(formData[personSchema.prefix][scheme.model])"
or
v-model="resolveObject([personSchema.prefix] , [scheme.model])"
There you can do handle the dot-notation and return the proper nested property.
I don't think it's possible directly with v-model, you can take a look at:
https://v2.vuejs.org/v2/guide/reactivity.html
Maybe the best solution would be use a watch (deep: true) as a workaround.
(I would try first to use watch properties inside formData[personSchema.prefix][scheme.model].)
I have been writing an API that uses GraphQL. I am still pretty new to it, and have been running into some problems regarding mutations. A simplistic form of my API has two record types. There is a contact record and a tag record. A contact record can have multiple tag records associated with it.
The schema I wrote for each of these record types are below:
const Tag = new graphQL.GraphQLObjectType({
name: 'Tag',
description: 'Categorizes records into meaningful groups',
fields: () => ({
_id: {
type: graphQL.GraphQLID
},
name: {
type: graphQL.GraphQLString
}
})
});
const Contact = new graphQL.GraphQLObjectType({
name: 'Contact',
description: 'Contact record',
fields: () => ({
_id: {
type: graphQL.GraphQLID
},
name: {
type: graphQL.GraphQLString
},
tags: {
type: new graphQL.GraphQLList(Tag),
resolve: function(src, args, context) {
return TagModel.findByContactId(src._id)
.then(tags => {
return Promise.map(tags, (tag) => {
return TagModel.findById(tag.tag_id);
});
});
}
}
})
});
I can make a mutation easy enough on records such as tags since they don't contain nested records of their own, but I'm not sure how to make a mutation on a record like contacts since it can contain tags as well. The mutation code I put in place looks like this:
const Mutation = new graphQL.GraphQLObjectType({
name: 'Mutation',
fields: {
createContact: {
type: Contact,
description: "Create Contact",
args: {
name: {type: new graphQL.GraphQLNonNull(graphQL.GraphQLString)},
tags: {type: new graphQL.GraphQLList(Tag)}
},
resolve: function(source, args) {
return ContactModel.save(args.name);
}
}
}
});
I'm not sure how to complete the resolver in the mutation in order to be able to save a contact and tag records at the same time. For instance, if I made a mutation query to save a new contact record with a new tag like this:
{"query": "mutation createNewContact {
contact: createContact (name: "John Smith", tags { name: "family" } )
{_id, text, tags { name } } }" }
Is there something special that I need to do in my mutation schema in order to allow for this type of mutation to happen?
You can't use Tag as an input object type, you would have to create a type like TagInput
const TagInput = new GraphQLInputObjectType({
name: 'TagInput',
fields: {
_id: { type: GraphQLID },
name: { type: GraphQLString }
}
});
It is recommended to always create Input version of your normal type. You could do the same with Contact by creating ContactInput. Then you could create a mutation in very similar way you did it
const Mutation = new GraphQLObjectType({
name: 'Mutation',
fields: {
createContact: {
type: Contact,
args: {
contact: { type: new GraphQLNonNull(ContactInput) },
tags: { type: new GraphQLList(TagInput) }
},
resolve: (root, args, context) => {
console.log(args);
// this would console something like
// { contact: { name: 'contact name' },
// tags: [ { name: 'tag#1' }, { name: 'tag#2' } ] }
// here create contact with tags
}
}
});
The query you would run would look like that
{
"operationName": "createContact",
"query": "mutation createContact($contact: ContactInput!, $tags: [TagInput])
{
createContact(contact: $contact, tags: $tags) {
_id
text
tags {
name
}
}
}",
"variables": {
contact: { name: "contact name" },
tags: [ { name: "tag#1" }, { name: "tag#2" } ]
}
}
I have been trying to create two collection with a common model kind. I am getting the following error:
"Uncaught enyo.Store.addRecord: duplicate record added to store for kind app.ImageModel with primaryKey set to id and the same value of 67774271 which cannot coexist for the kind without the ignoreDuplicates flag of the store set to true ".
Following are the two collection i have defined...
enyo.kind({
name: "app.FeatureCollection",
kind: "enyo.Collection",
model: "app.ImageModel",
defaultSource: "appF",
...
...
});
enyo.kind({
name: "app.SearchCollection",
kind: "enyo.Collection",
model: "app.ImageModel",
defaultSource: "appS",
...
...
});
And the model which i am using is as follows:
enyo.kind({
name: "app.ImageModel",
kind: "enyo.Model",
readOnly: true,
....
....
});
At one point i am setting like this:
this.set("data", new app.FeatureCollection());
and in another,
this.set("data", new app.SearchCollection());
I am not able to find out what could generate the error. I even tried to set "ignoreDuplicates" to true in model...but still the error comes. Any suggestion where i could be going wrong.
The ignoreDuplicates flag is expected to be set on enyo.Store and not enyo.Model:
enyo.store.ignoreDuplicates = true;
Are you using the fetch method of enyo.Collection to retrieve your data? If so, you might consider setting the strategy property to merge in your fetch call so that you have a single record for each unique image from your dataset, i.e.:
myCollection.fetch({strategy: "merge", success: function(rec, opts, res) {
// do something after data is retrieved
}});
I'm not seeing a problem with the pieces of code you provided. I created a sample on jsFiddle and it works as expected.
http://jsfiddle.net/z7WwZ/
Maybe the issue is in some other part of your code?
enyo.kind({
name: "app.FeatureCollection",
kind: "enyo.Collection",
model: "app.MyModel"
});
enyo.kind({
name: "app.SearchCollection",
kind: "enyo.Collection",
model: "app.MyModel"
});
enyo.kind({
name: "app.MyModel",
kind: "enyo.Model",
readOnly: true,
defaults: {
firstName: "Unknown",
lastName: "Unknown"
}
});
enyo.kind({
name: "App",
components: [],
bindings: [],
create: enyo.inherit(function (sup) {
return function () {
sup.apply(this, arguments);
this.collection1 = new app.FeatureCollection(this.data1);
enyo.log("Collection1(0) >>> " + this.collection1.at(0).get("lastName"));
this.collection1.at(0).set("lastName", "Smith");
enyo.log("Collection1(0) >>> " + this.collection1.at(0).get("lastName"));
this.collection2 = new app.SearchCollection(this.data2);
enyo.log("Collection2(0) >>> " + this.collection2.at(0).get("lastName"));
this.collection1.at(0).set("lastName", "Jones");
enyo.log("Collection2(0) >>> " + this.collection1.at(0).get("lastName"));
};
}),
data1: [{
firstName: "Hall",
lastName: "Caldwell"
}, {
firstName: "Felicia",
lastName: "Fitzpatrick"
}, {
firstName: "Delgado",
lastName: "Cole"
}],
data2: [{
firstName: "Alejandra",
lastName: "Walsh"
}, {
firstName: "Marquez",
lastName: "James"
}, {
firstName: "Barr",
lastName: "Lott"
}]
});
new App().renderInto(document.body);