Sencha Touch 2 Model Convert Function not Called when Reloading Store - extjs

I have a list which reads from a store whose model has a convert function on a field. The convert function returns a value that I use to control what appears in my list. This works fine the first time I load the store. The next time I load the store by setting extraParams on the store's proxy, it does not run through the convert function on the model, and therefore I am unable to update the display in my list.
Is there something I can do to ensure the model's convert function is called each time I load the store?
Thanks for your help
Example convert function:
{
name: 'myDisplayField',
type: 'string',
convert: function (value, record) {
if (value == null) {
var req = record.get('otherField');
if (req == "valueString") {
value = 1;
}
else {
value = 0;
}
}
return value;
}
}

You could probably use the refresh event listener for your store and have your function called every time your store reloads. http://docs.sencha.com/touch/2-0/#!/api/Ext.data.Store-event-refresh

Related

Build URL with form parameters to send and share same values between two clients

In an Angular application I have a form filters (multi select directive). Whenever a filter value is selected, it has to be included in the URL.
The goal is to be able to copy the URL with the form parameters and values and being able to send it to another client. In this way the second client would open the same page and all its fields would be already filled with the same values used by the first client.
At the moment every value selection triggers a function that encodes the parameter and the relative value and adds it to the current URL.
function obj_to_query(obj) {
var parts = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
for (var i = 0; i < obj[key].Keys.length; i++) {
if (encodeURIComponent(obj[key].FilterType) == 1) {
parts.push(encodeURIComponent("areas=" + obj[key].Keys[i]));
}
else if (encodeURIComponent(obj[key].FilterType) == 2) {
parts.push(encodeURIComponent("categories=" + obj[key].Keys[i]));
}
}
}
}
return "?" + parts.join('&');
}
Is there a better way to achieve the same result?

Re-use array collection on multiple pages

I currently have 2 pages, page1.php and page2.php, each of the pages uses a controller that completes its own functions etc.
However there are tabs within the pages that are exactly the same that gets a promise from a factory within the module. The lists are exactly the same except for querying on different IDs. For example both controllers have this:
pageListFactory.getData().then(function (result) {
$scope.BasicItems = result; $scope.basicItemsList = [];
angular.forEach($scope.BasicItems, function (BasicItem) {
angular.forEach(BasicItem['SomeInnerArray'], function (BasicSomeInnerItem) {
if (BasicSomeInnerItem == VARIABLE_THAT_CHANGES) {
$scope.basicItemsList.push({
ID: BasicItem.ID, Title: BasicItem.Title
});
}
});
});
});
So this code is used, and the VARIABLE_THAT_CHANGES is just what changes each time. However as I said it is used on multiple pages, is there a way to create just one function call and then each page just can call a specific bit and send the variable with it?
I tried using $rootScope but of course this just clogs and slows, and I'm not exactly happy on constantly using $rootScope to pass the $scope.basicItemsList around as the list could get quite big.
So is there any way to reuse this code without just copying and pasting it into each controller?
Sure you can re-use it...
Convert the factory to a service, its basically a name change, create a local variable to store the data, update the data on first call, and then grab the data if it exists on the second call.
.service('myService', ... stuff ... { // I suggest using a service, as I don't know if a factory would act as a singleton
var myData = null;
return {
getData: function(){
if(myData != null)
return myData; // returns data
else {
return $http()... // ajax call returns promise
}
},
setData: function(dataToSet){
myData = dataToSet;
}
}
Then your controllers:
//controller 1
var promiseOrData = pageListFactory.getData();
if(promiseOrData instanceOf Array){ // or whatever data you expect
$scope.BasicItems = promiseOrData;
....
}
else { // should be a promise
promiseOrData.then(function (result) {
pageListFactory.setData(result); // set the data once you get it.
$scope.BasicItems = result; $scope.basicItemsList = [];
....
}
}
In controller 2 you only need to get the data as the returned data will be an array, not a promise
On top of all this, write a directive which will process the data when you pass it along, then you can pass the variableThatChanges and have the directive take care of it.
Use services and write the function in that service and pass the variable VARIABLE_THAT_CHANGES into it. By this you can reuse the code.

Run a function when variables are loaded

I have an NgComponent that is supposed to load data from another file based on a parameter in the tag. Here is an example tag:
<line-graph width="800" height="250" src="table.csv" />
If I attempt to load data based on the src variable in the constructor, it is null. I know that the value is being set, just at a later time. Is there a way to call the load function when the element is full initialized and the variables have been loaded from that DOM?
implement NgAttachAware and run your code in attach().
I read about a bug that even this is not working with some directives recently.
In this case try to run the code inside attach with new Future(() { your code here });
To make code execute every time the value is changed you can make src a setter and the code in the setter gets executed every time the value is changed.
String _src;
#NgTwoWay('src')
String get src => _src;
set src(String val) {
_src = value;
// your additional code goes here
}
You can accomplish this by using the $watch function. The $watch function will be renamed to watch in the next version. Here is an example implementation:
class Component {
#NgAttr("src")
String src;
Scope scope;
Component(this.scope){
scope.$watch(() => src, (value, previousValue){
if (value == null) return;
//load and draw data
})
}
}
In the next version it will look something like this:
class Component {
#NgAttr("src")
String src;
Scope scope;
Component(this.scope){
scope.watch(src, (value, previousValue){
if (value == null) return;
//load and draw data
})
}
}

Iterating through parent entity to return array of child entities

I am trying to build an array of entities from a server query that exist in an object arrays
The diagram below illustrates my model:
In my datacontext, I've applied the following code:
function getByDboardConfig(dboardConfig) {
var busUnitDims = [];
var busUnitsTotalCount = dboardConfig.busUnits.length;
var buCount = 0;
dboardConfig.busUnits.forEach(function (busUnit) {
eq.from('BusUnitDimensions') // eq = breeze.EntityQuery
.where('busUnitId', '==', busUnit.id)
.using(em).execute() // em = EntityManager
.to$q(succeeded, failed); // using Angular, thus to$q
});
function succeeded(data) {
buCount++;
data.results.forEach(function (result) {
busUnitDims.push(result);
});
if (buCount === busUnitsTotalCount) {
console.log(busUnits.length);
return busUnitDims;
}
}
}
When I log to the console as show the length of the array, I get the correct entity count, but when I return the result of this call to my controller I get undefined. Not understanding why?
I've tried returning $q.when(busUnitDims) as well but I still get undefined.
The problem with your code is that the function is not returning anything, even if you relocate the return line outside the succeeded block
, it may return before filling the array is finished(notice you're executing the query asynchronously )
Neverthless, looking at your code; I take it you are getting the busUints and then query for each of their line items BusUnitDimensions separately;
that could mean many roundtrips to the server.
Anyways, you aim to fetching busUnits along with their related BusUnitDimensions (eager loading).
Although you didn't provide an idea of how your view model or your controller looks like; I assume you have one view for DboardConfig and another view for both related busUnits and BusUnitDimensions
so your workflow is:
Get a list of DboardConfigs
for each DboardConfig, load it's busUnits along with BusUnitDimensions
Hence, your function could be :
function getByDboardConfig(dboardConfig) {
return eq.from("busUnits")
.where("dboardConfigId", "==", dboardConfig.id)
.expand("BusUnitDimensions")
.using(em).execute() // em = EntityManager
Then inside your controller:
$Scope.getBusUnitsandDimentions = function () {
dataservice.getByDboardConfig($Scope.dboardConfig)
.then(succeeded)
.fail(failed);
};
function succeeded(data) {
$Scope.busUnits = [];
data.results.forEach(function (result) {
$Scope.busUnits.push(result);
});
}
}
}
This way, you can remove the coding for fetching busUnits since we've already fetched it with it's related child table.
Simply put:
busUnits to get your array of bus units for a specified DboardConfig
busUnits.BusUnitDimensions to get it's related dimensions

no of records in a store are not returning in extjs

I am new to extjs and was working on creating a dynamic screen depending on the no of records from the Ext.data.store(); getTotalCount/getCount are used to get the no of records from the store. I need to store the total no of records in a var and return it
I am trying to do something like this
function Get_count()
{
var num;
CacheStore.on({
'load':{
fn : function(store,records,options){
num = getTotalCount();
//console.info('Store count = ', tsize);
//console.info(' count = ', getCount());
},
scope: this
},
'loadexception' : {
fn : function (obj,options,response,e){
//console.info('error = ', e);
},
scope : this
}
});
// this is a wrong logic but have to do something similar
//return num; //return num
};
tsize = Get_count();
I always get null in tsize. I also tried getCount() instead of getTotalCount() butI am getting the same problem.
dont know where I am going wrong
Your logic is a bit poked here. You can't fire a function that will add a listener to a store that will hook when the store has finished loading. ( well you can, but this is a subtle bug down the line ).
What you need to do is declare a listener on the store when you create it, that contains the function you wanna use the number in.
cacheStore =Ext.create...
cacheStore.on('load',function(store,records,e){
//dosomestuff that needs the count
var num= store.totalCount()
//now you use the num in here, else you create an async error
//or you can ...
my.someFunc(num);
//in here, but you can only run it after the store has loaded
},this);

Resources