I have multiple listeners in my initialize for my view, looks like this:
this.collection.on('reset', this.render);
this.collection.on('add', this.render);
this.collection.on('change', this.render);
I'm curious if there's a way to combine all of them since they all fire the render
May be you can try
this.collection.on("reset add change", this.render);
Look at this. It works as its displayed there, but not sure about binding it with default collection events.
Related
So I have setup a model/table that users will use as a project task list. I would like it so that when they change the Status (a field in the model) of an item to either Completed or Cancelled it is hidden.
That way they are only dealing with active entries. But I would also like them to be able to view these hidden (archived) items if needed.
I added the following code to the onAttach option of the table
var datasource = app.datasources.Projects;
datasource.query.filters.Status._notContains = 'Completed';
datasource.load();
And then I have a button with the following code so they can see hidden/archived items:
widget.datasource.query.clearFilters();
widget.datasource.load();
app.closeDialog();
var datasource = app.datasources.Projects;
datasource.query.filters.Status._contains = 'Completed';
datasource.load();
It works, but I feel like there might be a better/more elegant way to accomplish this. Especially since it looks like the app has to load then data, THEN filter it (which results in a slower load). (I think I might have some redundant code in there as well)
Also I feel like I am missing something with my syntax, because I can't get it to filter out Completed AND Cancelled.
Thank you for your help!
If you have a single page of items in the table and there aren't many items, then you can filter on the client side. For example, you can use a binding expression to add a "projectHidden" style to the row based on some logic and then use CSS to change the visibility of the row.
For your second code block, there is no reason to clear filters, load, set the filters and then load again. Just clear the filters, set the new filter, and call load. Also if you are manually controlling the query load, then you might want to uncheck the setting in the data source to automatically load data.
var datasource = app.datasources.Projects;
datasource.query.filters.Status._notEquals = 'Completed';
datasource.query.filters.Status._notEquals = 'Cancelled';
datasource.load();
I have a simple master/details relationship where one order can have multiple revenue allocations. The order has a collection that contains these.
I want to sum a property in my revenue allocation objects and ensure that it adds up to my order total. However, if I databind on the count property of the allocations collection this gets called when you first add an empty object and not when that object has been populated. So an empty allocation is added at the time the "Add allocation" screen is created and the databind function called. That of course means that when the save button on the "Add allocation" screen is clicked, the databind function isn't called again.
Anyone got any ideas? I basically want my databind function to be called when the save button is clicked in the "add screen" and not before.
This is the HTML client - NOT Silverlight
I'm pretty sure that the solution would be to use an OData query to get your aggregate data within the databinding function of the save button - or perhaps a separate button (e.g. "Tally Order Totals"). Exactly how you do that? A bit too hard for me to answer right now, but start with a new button TallyOrderTotals and a new data field for your total. Edit the post_render event for TallyOrderTotals and lookup the allocations in the javascript in which you data bind the value of the new data field.
Somewhere you will need a piece of code that looks something like this:
myapp.activeDataWorkSpace.<datasource>.RevenueAllocations
.filter("OrderID eq " + msls._toODataString(<orderID>, ":String"))
.execute()
.then(function (result) {
// assign the result somewhere
}
I'm not saying that's something you can cut-and-paste - but definitely look at the msls.js documentation and see what you can do with querying your data inside the event context.
One quick point however - if you only need to calculate that total as a verification step, consider doing it in the SaveExecuting() event on the server side. This will allow you to throw an exception back up the tree to your HTML page which the msls.js script should render on the client side.
Hope that helps. :)
I'm trying to wrap my head around Meteor's way of dealing with reactivity and I want to make sure I've got some concepts right.
Take the follow reactivity example:
A user types something into a form field. The thing that he is typing is instantly displayed somewhere else on the page, as the user is typing, letter by letter. An instantaneous duplication.
From what I know about Angular, this is a very common example of reactivity. Angular binds the input directly to the output on the client side. There's nothing in between.
Correct me since I could be wrong, but Meteor can do this, but the input would first need to be captured and stored into a Mongo + MiniMongo DB (perhaps only as a collection in local storage), there would need to be a subscribe step, and those values would then be read and displayed on the page.
Is there a way to directly bind an event on the front end to another thing on the front end like Angular does?
Is this right? For Meteor to have the front-end-only reactivity of Angular it must first go through the intermediary of a collection, meaning extra code would be necessary to accomplish this compared to Angular?
The example in the Meteor Docs:
Deps.autorun(function () {
Meteor.subscribe("messages", Session.get("currentRoomId"));
});
So here, when the data of currentRoomId changes, the function is reactive to that data change and the function runs (in this case Meteor subscribes to messages).
Using Session variables is the only way I see of possibly binding two parts of a view together directly. Are there other ways?
Meteor's client-side reactivity system (Deps) is not coupled with its live MongoDB syncing. You can use it with any reactive data source which implements the right interface, including data sources which are entirely client-side. For example, you can use the built-in Session object. This is just a client-side key-value store with support for Meteor's reactivity, and you don't have to do any publish or subscribe to use it.
This standard way to do this sort of thing looks something like this:
<input id="field" value="{{fieldValue}}">
Template.form.fieldValue = function () {
return Session.get("fieldValue");
};
Template.form.events({
"input #field": function (evt) {
Session.set("fieldValue", $(evt.currentTarget).val());
}
});
Now the Session variable fieldValue is synced up to the form field. You can call Session.get("fieldValue") in some helper and that template will re-render when the user types in the form field. And if you call Session.set("fieldValue", "blah") then the form field will update itself.
As for your edit: You can make your own reactive data sources using Deps.Dependency, or you could meteor add reactive-dict although that's not documented. There may be packages on Atmosphere.
printableInvoice.addEventListener(batchGenerated, printableInvoice_batchGeneratedHandler);
Results in this error:
1120: Access of undefined property batchGenerated. I have tried it as FlexEvent.batchGenerated and FlashEvent.batchGenerated.
The MetaData and function that dispatches the even in the component printableInvoice is all right. It I instantiate printableInvoice as an mxml component instead of via action-script it well let put a tag into the mxml line: batchGenerated="someFunction()"
Thanks.
batchGenerated should be a string.
It looks like your application dispatches an event whenever the batch is generated.
I'm assuming inside your code you have something along the lines of either:
dispatchEvent( new BatchEvent("batchGenerated") );
or
dispatchEvent( new BatchEvent(BatchEvent.BATCH_GENERATED) );
The second way is usually preferred as using variables instead of magic strings gives you an extra level of compile time checking.
The first required parameter of events is typically the type of the event - Event.CHANGE (aka "change"), FlexEvent.VALUE_COMMIT (aka "valueCommit") etc.
This is what the event listener is actually comparing against.
So in your event listener code above, you would want to change the line to be either:
printableInvoice.addEventListener("batchGenerated", printableInvoice_batchGeneratedHandler);
or hopefully
printableInvoice.addEventListener(BatchEvent.BATCH_GENERATED, printableInvoice_batchGeneratedHandler);
If you want to go further, the Flex documentation goes into some detail as to how the event system works, and how the events are effectively targeted and handled through the use of the Capture, Target, and Bubble phases.
I'm working on a Flex 3 project, and I'm using a pair of XMLListCollection(s) to manage a combobox and a data grid.
The combobox piece is working perfectly. The XMLListCollection for this is static. The user picks an item, and, on "change", it fires off an addItem() to the second collection. The second collection's datagrid then displays the updated list, and all is well.
The datagrid, however, is editable. A further complication is that I have another event handler bound to the second XMLLIstCollection's "change" event, and in that handler, I do make additional changes to the second list. This essentially causes an infinite loop (a stack overflow :D ), of the second lists "change" handler.
I'm not really sure how to handle this. Searching has brought up an idea or two regarding AutoUpdate functionality, but I wasn't able to get much out of them. In particular, the behavior persists, executing the 'updates' as soon as I re-enable, so I imagine I may be doing it wrong. I want the update to run, in general, just not DURING that code block.
Thanks for your help!
Trying to bind the behaviour to a custom event rather than the CHANGE event.
I.e. do what you are doing now, but dispatch and handle a custom event to do the work.
Have you considered using callLater?
Does direct manipulation of XMLListCollection's source XMLList have the same results?
Have you considered something like:
private function changeHandler( event:Event ):void
{
event.target.removeEventListener( event.type, changeHandler );
// your code here.
event.target.addEventListener( event.type, changeHandler );
}