How to set columnOption looping throw all column? - devexpress

How to set the columnOptions looping through all in angular devexpress module?
at present I do one by one like :
onInitialized(e) {
e.component.columnOption("Id", {
allowHeaderFiltering : false -> 1
})
e.component.columnOption("Name", {
allowHeaderFiltering : false -> 2
})
e.component.columnOption("SaleAmount", {
editorOptions: {
format: "currency",
showClearButton: true
}
});
}
How to look all column and set the columnOptionon each?

If you need to initialize a column with default settings (I believe you need to do this since you provided the onInitialized event handler code), use the customizeColumns callback function. Its parameter is an array of all columns in the grid. Thus, you can traverse through all columns as you do in a regular array.
Since customizeColumns is a callback function, use square brackets to assign a function to it in Angular as described in the Callback Functions section:
*.component.html
<dx-data-grid [customizeColumns]="customizeColumns">
</dx-data-grid>
*.component.ts
export class AppComponent {
customizeColumns (columns) {
columns.forEach(c => c.width = 100);
}
}

Related

How can I use an event to select a query selector to select an entity to copy the rotation of another entity?

In this component code I am trying to use an event to select the meaning of the variable called "name"
to select which entity will copy another entities rotation as the user watches.
Different events will result in different rotations.
So event 1 means that name equals querySelector Object A
Then I am trying to have row get it's own rotation and give it to name's (to) animation and then start
name's animation by emitting moveobject to name.
However I am currently stuck on this problem after investing many hours trying to solve it. Help?
AFRAME.registerComponent("comp", {
init: function () {
let name = {}
this.el.addEventListener("event1", (e) => {
name = document.querySelector('#objectA');
console.log('event1')
// line 13? comp.emit('rowstart)
});
this.el.addEventListener("event2", (e) => {
name = document.querySelector('#objectB');
console.log('event2')
});
let row = document.querySelector('#rowA');
row.addEventListener('rowstart', function (e) {
var rotation = row.getAttribute('rotation')
name.setAttribute('animation', {
to: {
x: rotation.x,
y: rotation.y,
z: rotation.z - 30
}
})
name.emit('moveobject')
});
}
});
I should mention that this link below is what my code looks like when it is ONLY copying rotation, and not using an event to select which entity will be rotated https://glitch.com/edit/#!/copy-rotation?path=index.html:37:8 (edited)
to is not a vector property, you have to pass it as a string.
name.setAttribute('animation', 'to', `${rotation.x} ${rotation.y} ${rotation.z}`);

NGRX: Composing state when we have to represent data from two lists

Practical example: Consider an expand/collapse list. Each item expands another list.
export interface MainDomainList {
id: number
name: string;
}
export interface SubDomainList {
id: number
name: string;
}
export interface AppState {
mainDomainList: MainDomainList[];
subDomainList: SubDomainList[];
}
On the UI the list should be represented like this:
MainDomainList[1]
SubDomainList[] (entire list)
MainDomainList[2]
Another SubDomainList[] (entire list)
etc..
When the user clicks on the MainDomain[n] there is a call to the backend which returns a list of SubDomain[]. There are no connections between the two of them.
It seems that the most complicated part is that the SubDomains are being loaded one by one on click not all at once, and multiple MainDomains can be open at the same time like in the example above. Also, it should be possible to easily perform CRUD operations on the subDomainList entities.
I tried using a selector which selects an item from the state by id but every time the state is overridden.
My initial idea was to create a separate state in which after the SubDomainList[] is loaded successfully, then I could add the loaded SubDomainList[] by dispatching an 'ADD' action thus adding the entities and the id of the clicked MainDomainList in the newList state as the user clicks on through the list obtaining something like this:
exportt interface AppState {
mainDomainList: MainDomainList[];
subDomainList: SubDomainList[];
newList: NewList[];
}
{
mainDomainList : {
entities: {
md1: {
id: 'md1',
name: '1'
},
md2: {
id: 'md2',
name: '2'
}
}
},
subDomainList : {
entities : {
sd1 : {
id : 'sd1',
name: 'name1'
},
sd2 : {
id : 'sd2',
name: 'name2'
}
},
newList : {
entities : {
md1 : {
id : 'md1',
subDomainList: [{}, {}]
},
md2 : {
id : 'md2',
subDomainList: [{}, {}]
}
}
}
}
Then somehow i would get all the newList entities and match them in the UI with the id of the MainDomainList[n].id
Is my approach correct or is there any other better or less complicated solution for this issue?
I'm fairly new to the subject but I had a lot of headaches trying to figure out how to implement this with ngrx/Entity and failed so far, although it should be a pretty common case. Any help would be much appreciated.
You can write selectors with argument by passing of main domain list
ref: ngrx parameter to select function
and https://blog.angularindepth.com/ngrx-parameterized-selector-e3f610529f8

Binding custom element in initial loading

In aurelia: I have a string interpulation over object property that works fine in the app.html - it shows number of accounts:
ALL ACCOUNTS (${userAccountsData.length})
In the initial loading, I see that the value changes after few milliseconds from 0 to the actual value (data is retrieving from the service), but - when trying to show aggregate data (count number of active accounts) over the same data in a template (custom element) - the data stays as 0 and not updated as the userAccountsData.length
*When refreshing again after the initial loading - the data is shown as it should be.
This is the custom element instance in the app.html:
<account-status-selection-bar accounts-data.bind="userAccountsData"></account-status-selection-bar>
And this is part of the HTML of the custom element itself:
<template>
<div ref="active"
class="selection">${accountActivationDistribution.numberOfActiveAccounts}
This is the relevant part of the custom element VM:
"use strict";
import { bindable} from 'aurelia-framework';
export class accountStatusSelectionBar {
#bindable accountsData;
constructor() {
this.accounts = [];
this.accountActivationDistribution = { numberOfActiveAccounts: 0,
numberOfInactiveAccounts : 0,
numberOfTotalAccounts : 0
}
get activeAccounts() {
var activeAccounts = this.accounts.filter(function(account) {
return account.IsApproved;
});
return activeAccounts.length;
}
attached()//bind()
{
this.accounts = this.accountsData;
this.accountActivationDistribution.numberOfActiveAccounts =
this.activeAccounts
}
In the app.js I use observerLocator - here is the code related to the working part of userAccountsData.length:
constructor() {
this.userAccountsData = [];
....
this.subscribe = this.observerLocator.getObserver(accounts, "all")
.subscribe((value) => {
if (!value)
return;
this.userAccountsData = value;
**A work around I found (although I'm not sure this is the best way) is to do the aggregation in the app.js (in the observer part) in object and bind the already aggregated object to the custom element - this is working. I'm still looking for the mentioned above solution.
It looks like the problem is you're binding userAccountsData to accountsData on your custom control; then assigning this.accounts = this.accountsData; and finally later you're reassigning userAccountsData in app.js.
Because accounts is not observing or bound to the original userAccountsData, it maintains the reference to the original array (which is set to an empty array) and never gets updated.
There is a race condition on refresh, where some cache probably means that userAccountsData gets the updated value before the binding occurs, which is why it works sometimes.
The solution is to remove some of the reassignment and just bind directly to accounts and forget the intermediate accountsData.
I created a gist here showing the different behaviour.

Bind an observable property to a collection function?

I have a class Market which contains a collection of MarketUpdate objects called m_updates. For the UI I am using type-safe builders to create columns in a tableview like so:
override val root = tableview<Market> {
val sortedMarketList = SortedList<Market>(markets)
sortedMarketList.comparatorProperty().bind(this.comparatorProperty())
items = sortedMarketList
...
column("Strikes", Market::m_strikes)
...
The m_strikes property is just a SimpleIntegerProperty directly owned by a Market object. However, I need to be able to build columns like these:
...
column("Created At", Market::m_updates::first::m_time)
...
...
column("Last Update", Market::m_updates::last::m_time)
...
where m_time is a SimpleLongProperty owned by a MarketUpdate object. When a Market object is updated, a new MarketUpdate object is added to the end of the m_updates collection. This means that the binding needs to automatically transition from one object to another, and that the tableview needs to be notified and update itself to reflect the data in the new object. I think binding by way of the first() and last() functions of the collection as described above captures the idea in a very simple way, but it won't compile.
There are many properties like m_strikes and m_time. How can I achieve this gracefully?
If I understand your use case, what you want to do is to create an observable value that represents the time property for the first and last updates in a given Market object. To do that, you can create an objectBinding based on the updates list inside of each Market object, then extract the first() or last() element's timeProperty. In the following example, the TableView will update as soon as you augment the updates list in any Market object.
Bear in mind that the example requires each Market to have at least one update. If this isn't your case, make sure to handle null accordingly.
class Market {
val updates = FXCollections.observableArrayList<MarketUpdate>()
}
class MarketUpdate {
val timeProperty = SimpleObjectProperty(LocalDateTime.now())
}
class MarketList : View("Markets") {
val markets = FXCollections.observableArrayList<Market>()
val data = SortedFilteredList<Market>(markets)
override val root = borderpane {
prefWidth = 500.0
center {
tableview(markets) {
column<Market, LocalDateTime>("Created at", { objectBinding(it.value.updates) { first() }.select { it!!.timeProperty } })
column<Market, LocalDateTime>("Last update", { objectBinding(it.value.updates) { last() }.select { it!!.timeProperty } })
}
}
bottom {
toolbar {
// Click to add an update to the first entry
button("Add update").action {
markets.first().updates.add(MarketUpdate())
}
}
}
}
init {
// Add some test entries
markets.addAll(
Market().apply { updates.addAll(MarketUpdate(), MarketUpdate(), MarketUpdate()) },
Market().apply { updates.addAll(MarketUpdate(), MarketUpdate(), MarketUpdate()) },
Market().apply { updates.addAll(MarketUpdate(), MarketUpdate(), MarketUpdate()) },
Market().apply { updates.addAll(MarketUpdate(), MarketUpdate(), MarketUpdate()) }
)
}
}
I've used a SortedFilteredList to make it easier to deal with sorting. The reason sort works here, is that the columns are actually represented by LocalDateTime values.
I hope this gives you some ideas :)

Meteor: sharing variables between helpers

I am currently building a quizz app in Meteor and have three function within helpers
Template.quizPage.helpers({
//this helper finds the currentquiz and returns the currentquestion to the template
question: function(){
currentquiz = this.quiztitle;
currentQuestion = Session.get('currentQuestion') || 0;
return Quizzes.findOne({'quiztitle': currentquiz}).quizquestions[currentQuestion]
},
length: function (){
questionlength = $(Quizzes.findOne({'quiztitle': currentquiz}).quizquestions).length;
return questionlength;
},
answers: function(){
currentquiz = this.quiztitle;
currentQuestion = Session.get('currentQuestion') || 0;
return Quizzes.findOne({'quiztitle': currentquiz}).answers[1][currentQuestion]
}
});
As you can see some of this code is already duplicate (currentquiz = this.quiztitle). How can I share currentquiz between functions within a helper?
This is becoming a real problem as I need to define the variable currentquiz one time
currentQuestion = [0,0,0,0,0];
But current code resets the currentquestion any time I activate the helper in the template. I can;t define it above the function $(document.ready) wrap to set the variable or define it . This should be really easy right?
i know this is an old thread but I just came across the same problem. What you can do is define a reactive variable on the template level:
var abc;
Template.XY.rendered = function(){
abc = new ReactiveVar("abc");
},
Template.XY.helpers({
someFunction:function(){
return abc.get();
}
)}
I define a var abc; to bind the variable to the template instance (i guess this can also be done with this.abc = new ... )
To provide a variable available in the template helpers and events you just need to add it in the template instance.
In the onCreated function you can access the template instance with the keyword this.
Template.myTemplate.onCreated(function(){
this.mySharedVariable = new ReactiveVar("myValue");
});
In the helpers you can access to the templace instance with Template.instance().
Template.myTemplate.helpers({
myHelper1(){
const instance = Template.instance();
instance.mySharedVariable.get(); // Get the value "myValue"
// Do something
},
myHelper2(){
const instance = Template.instance();
instance.mySharedVariable.get(); // Get the value "myValue"
// Do something
}
});
In the events you can access to the template instance with the second parameter of the function.
Template.myTemplate.events({
'click .js-do-something' : function(event, instance){
instance.mySharedVariable.set("newValue"); // Set the value "newValue"
}
});
In the example above i'm using a ReactiveVar so if its value get changed the two helpers myHelper1 and myHelper2 will re-execute. But be free to use normal variable depending on your need.
PS: Because Session are global, you should not use Session if you only use this "shared" variable inside your template.

Resources