I am going to try to explain with out confusion: I am using the Three20 Library
I have a PostEdit class that contains a xib and class that creates a "popup" calls Edit Post (image below), over an existing view (PostSearch) so that the user does not have to leave the screen when they are trying to edit a Forum Posting they created.
So when the user pushes the send button and the data is sent back to the server, i want to invalidateModel back the PostSearch class (Model/DataSource). This is where I have not clue what to do.
I have even tried this with out success in my PostEdit class.
PostSearch *post = [[PostSearch alloc] init];
[post Invalidate];
[post invalidateModel];
[post invalidateView];
[post release];
I am not sure I understand what you are trying to do; in any case, I will try to answer assuming that PostSearch is a controller that lies below PostEdit; after editing a post and clicking done, you want to update PostSearch.
If this is correct, then what you need to do is access the PostSearch object which is already existing and currently displayed under PostEdit. E.g., you could:
pass a reference to PostSearch when you create your PostEdit; then in the done button handler you would invalidate its model; or,
register your PostSearch object for a notification (through the NSNotificationCenter) that PostEdit would fire when Done is tapped; or,
use a "brute-force" approach and in your PostSearch viewWillAppear do the invalidation.
I have never used the invalidateModel method. What I do when I need to refresh my data, is:
self.model = nil;
self.model;
you could also give this a try.
Related
I'm trying to get the "Get Products" ribbon action logic in the main Invoice form to be executed automatically when the form is in update mode.
The invoice is created through a business flow, that starts with an Opportunity.
Here's the code form the load event of the invoice onLoad event:
onFormLoad = function () {
//if we are in update mode...
if (Xrm.Page.ui.getFormType() == 2) {
//if no products are present in the list...
if (loadInvoiceProducts().length == 0) {
Mscrm.CommandBarActions.getProducts();
}
}
};
loadInvoiceProducts = function () {
//just a jQuery ajax call to the oData service... this works.
var products = oDataQuery("InvoiceDetailSet?$filter=InvoiceId/Id eq guid'" + Xrm.Page.data.entity.getId() + "'");
return products.results;
};
This works fine if I manually create a new order (the form is then in form mode == 1, create) and when I fill in the required fields and save, the form reloads in update mode, then the "Get Products" popup appears.
The problem is when the invoice is created through the business flow. The invoice form opens in create mode (through the business flow, all the required fields are already filled) and when I hit Ctrl-S, the code above is triggered, the form is in update mode, but then another refresh happens and then the code above is not run.
I have to hit F5 for it to be triggered again.
Has anyone attempted anything like this before ?
Thanks.
Recent versions of CRM have asynchronous form loading and refreshing, which is likely what you're running into. When a new record is created and saved, onload is triggered again, as you've noted. When an existing record is updated and saved, onload is not triggered again. To learn more about what's going on, add an onsave handler that cancels the save, like this:
// Put this function into your script
function cancelSave(econtext) {
var eventArgs = econtext.getEventArgs();
console.log("saveMode", eventArgs.getSaveMode()); // could help you figure out why form is saving
eventArgs.preventDefault();
}
// And then put this line into your onload method
Xrm.Page.data.entity.addOnSave(cancelSave);
If after adding the handler your issue goes away, then the problem is that your existing record is being saved which does not trigger onload again as I mentioned. You will need to investigate why the form is saving:
Do you have other code that could be triggering a save?
If the console output from cancelSave shows 70 ("AutoSave"), it is auto-save (which you can disable system-wide or on your form specifically [search the sdk for preventAutoSave])
If the console output from cancelSave shows 2 ("Save and Close"), then something on your form might be causing navigation to occur (when auto-save is enabled, navigating away from a form with unsaved data triggers a save with mode 2)
If you determine that it is a save event that is interfering but can't figure out where the save is coming from for some reason, then you can also take the approach of figuring out which form fields are dirty. Save events do nothing if there are no dirty fields, so if you could figure out and resolve the dirtiness, that would work around the problem. One easy way to see which fields are dirty is to enable auditing on the entity and then view the audit log to see which fields were changed with the save.
I am writing a simple test to create an element, see if it is there and then delete it to verify the integrity of my web app every time I build it.
I have a test:
$this->visit('admin/menu/samples')
->seePageIs('admin/menu/samples')
->click('New Sample')
->seePageIs('admin/menu/samples/new/create')
->type('test1', 'name')
->type('test2','description')
->type('test2','introduction')
->select(1, 'scenario_id')
->type('test','slug')
->press('Add')
->seePageIs('admin/menu/samples')
->delete('admin/menu/samples/'. \App\Sample::whereSlug('test')->first()->id )
->visit('admin/menu/samples')
->dontSee('test1');
it creates the Sample element fine, but as I have several Delete buttons ( for every Sample element in index, as they are in a list) I can't use the method click/press('Delete'). So I thought I'd just use the delete method, which I have already set up. The problem is that it will not delete the element that I have created. The delete request will not work.
I assure you that the route is there and the if I just press the Delete button my Sample element will be deleted.
Why can't I mimic this with PHPUnit, is there another way to delete?
I just had this same exact issue. Turns out its the CSRF token issue. Anytime you do a request other than the "GET" request, you will need to verify your CSRF token. Now Laravel does a good job already doing this when you are on the website itself, which is why submitting forms via "press" will work: http://laravel.com/docs/5.1/routing#csrf-protection. In my specific case, it seems my token is generated via an XSRF-Token cookie, which can be done via a simple check of the Request Headers.
However, if you use the url, you will need to generate a CSRF token manually. To do this, simply call csrf_token() and inject it into your call:
$this->visit('admin/menu/samples')
...
->delete('admin/menu/samples/'. \App\Sample::whereSlug('test')->first()->id,
['_token'=>csrf_token()],[] )
...;
Here was the article that helped me figure out how to inject the token, though dont confuse the method signatures of $this->call and $this->delete:
http://davejustdave.com/2015/02/08/laravel-5-unit-testing-with-csrf-protection/
I'm submitting an object to our API via a POST and then transitioning to a route that displays that object. The API modifies one or more fields in the object in the POST and returns the updated info in the request response.
The data displayed is the original data from before the POST to our API. I can see from the console that ember-data is receiving back the updated information from our API. How can I force ember to "refresh" the object so that it displays the correct info?
Matt. Yehuda Katz posted a reply to a user which provides this functionality:
https://stackoverflow.com/a/14183507/506230
Basically you create a record, apply it, save it, then reload it.
saveMessage: function(text){
var acct = Social.Account.find(this.get("id")),
msg = Social.store.createRecord(
Social.Message,
{
text: text,
account: acct,
created: new Date()
}
);
acct.get("messages").addObject(msg);
Social.store.commit();
var timeoutID = window.setTimeout(function(){
__msg.reload();__
console.log('reloading');
}, 250);
}
It turns out ember was actually behaving properly and no additional work was necessary. The problem is that I was setting a variable on the controller with the same name as a computed property on my model. The value of the variable on the controller was being displayed rather than the computed property. Changing the name of the controller variable resolved the issue without any additional code.
Using doctrine 2.1 (and zend framework 1.11, not that it matters for this matter), how can I do post persist and post update actions, that involves re-saving to the db?
For example, creating a unique token based on the just generated primary key' id, or generating a thumbnail for an uploaded image (which actually doesn't require re-saving to the db, but still) ?
EDIT - let's explain, shall we ?
The above is actually a question regarding two scenarios. Both scenarios relate to the following state:
Let's say I have a User entity. When the object is flushed after it has been marked to be persisted, it'll have the normal auto-generated id of mysql - meaning running numbers normally beginning at 1, 2, 3, etc..
Each user can upload an image - which he will be able to use in the application - which will have a record in the db as well. So I have another entity called Image. Each Image entity also has an auto-generated id - same methodology as the user id.
Now - here is the scenarios:
When a user uploads an image, I want to generate a thumbnail for that image right after it is saved to the db. This should happen for every new or updated image.
Since we're trying to stay smart, I don't want the code to generate the thumbnail to be written like this:
$image = new Image();
...
$entityManager->persist($image);
$entityManager->flush();
callToFunctionThatGeneratesThumbnailOnImage($image);
but rather I want it to occur automatically on the persisting of the object (well, flush of the persisted object), like the prePersist or preUpdate methods.
Since the user uploaded an image, he get's a link to it. It will probably look something like: http://www.mysite.com/showImage?id=[IMAGEID].
This allows anyone to just change the imageid in this link, and see other user's images.
So in order to prevent such a thing, I want to generate a unique token for every image. Since it doesn't really need to be sophisticated, I thought about using the md5 value of the image id, with some salt.
But for that, I need to have the id of that image - which I'll only have after flushing the persisted object - then generate the md5, and then saving it again to the db.
Understand that the links for the images are supposed to be publicly accessible so I can't just allow an authenticated user to view them by some kind of permission rules.
You probably know already about Doctrine events. What you could do:
Use the postPersist event handler. That one occurs after the DB insert, so the auto generated ids are available.
The EventManager class can help you with this:
class MyEventListener
{
public function postPersist(LifecycleEventArgs $eventArgs)
{
// in a listener you have the entity instance and the
// EntityManager available via the event arguments
$entity = $eventArgs->getEntity();
$em = $eventArgs->getEntityManager();
if ($entity instanceof User) {
// do some stuff
}
}
}
$eventManager = $em->getEventManager():
$eventManager->addEventListener(Events::postPersist, new MyEventListener());
Be sure to check e. g. if the User already has an Image, otherwise if you call flush in the event listener, you might be caught in an endless loop.
Of course you could also make your User class aware of that image creation operation with an inline postPersist eventHandler and add #HasLifecycleCallbacks in your mapping and then always flush at the end of the request e. g. in a shutdown function, but in my opinion this kind of stuff belongs in a separate listener. YMMV.
If you need the entity id before flushing, just after creating the object, another approach is to generate the ids for the entities within your application, e. g. using uuids.
Now you can do something like:
class Entity {
public function __construct()
{
$this->id = uuid_create();
}
}
Now you have an id already set when you just do:
$e = new Entity();
And you only need to call EntityManager::flush at the end of the request
In the end, I listened to #Arms who commented on the question.
I started using a service layer for doing such things.
So now, I have a method in the service layer which creates the Image entity. After it calls the persist and flush, it calls the method that generates the thumbnail.
The Service Layer pattern is a good solution for such things.
I am using Infragistics UltraGrid with datasouce Windows Bindingsouce.
On change, I provide datasouce to Bindingsouce and call DataBinding of UltraGrid. Value in the datasouce of Bindingsouce changes, but that is not reflected in the UltraGrid.
Your binding source must raise some event to trigger grid refresh. For example, if you are using BindingList it should raise the ListChanged event.
Also, make sure that whatever class that you are using as your Binding Object implements INotifyPropertyChanged so that when you update the BindingObject at run time it gets channeled to BindingSource which eventually gets picked up by Grid.
i.e.:
BindingList<Foo> lstItems = new BindingList<Foo>;
BindingSource bso = ;
bso.DataSource = lstItems;
Grid.DataSource = bso;
public class Foo : INotifyPropertyChanged
see MDSN article here
Also depends if you changing the collection outside Grid (at runtime, because if you do, you need to use BindingList<T> and assign it to BindingSource