質問

I have two Ajax calls. I need to make sure that a JS function is executed between these two calls.

Is it possible to trigger the execution of a client-side JS function via the AJAX response? Or how would you do this kind of thing?


EDIT My code, after doing what was suggested by the first answer (onComplete):

^ (html jQuery ajax
    callback: [ :text | id := self createNewAnnotation: text ]
    value: (self html jQuery: '#annotationText') value;

    onComplete: ((JSStream on: 'displayAnnotation("', id, '")'), 
        (self html jQuery ajax
            callback: [ :text | finalText := text ]
            value: (self html jQuery: '#text') html)
    );

What this is supposed to do: on the first callback, the value of the #annotationText field is passed to createNewAnnotation, which saves the annotation and returns the ID. Next, I want to pass that ID to the client-side JS function displayAnnotation().

In this example, this can't yet work, as the code around JSStream on: is not in a block and thus has the initial value of id. How can I pass that result of the server-side method as parameter to the client-side function?

役に立ちましたか?

解決

In Seaside, you probably would use the jQuery bindings to execute ajax calls. If you want to make sure that two ajax calls are chained and some other JS code is executed in between, the code would follow these lines:

renderContentOn: html
    html span
       onClick: (html jQuery ajax 
                    callback: [...1st ajax callback...];
                    onComplete: ((JSStream on: '... some JS code ...'),
                                 (html jQuery ajax callback: [...2nd ajax callback...]));
       with: 'Click this to trigger the calls'.

This will render a span that, when clicked, will execute the 1st ajax call. If that one completes, the JS code and the second ajax call will be executed.

EDIT:answer to the additional question:

If you want the 'id' that is passed on to the call of displayAnnotation to be computed by the first callback, you can only generate that call after the first callback has executed. The value can be passed between ajax callbacks via temporary variables or instance variables (because of closures). The following piece of code makes the chaining via onComplete: explicit. Afterwards, I give an example where less ajax calls are made.

^ (html jQuery ajax
    callback: [ :text | id := self createNewAnnotation: text ]
    value: (html jQuery: #annotationText) value;
    onComplete:  
        (html jQuery ajax 
              script:[:s | s << ((JSStream on: 'displayAnnotation("', id, '")')]
              onComplete:
                  (html jQuery ajax 
                       callback: [ :text | finalText := text ]
                       value: (html jQuery: #text) html)))

You can also reduce the number of ajax calls if you understand how Seaside callbacks work. In summary, the block that produces the response of the callback is always invoked last. This allows to group a number of callback blocks in a single call. Such as:

    ^ (html jQuery ajax
          callback: [ :text | id := self createNewAnnotation: text ]
          value: (html jQuery: #annotationText) value;
          script:[:s | s << ((JSStream on: 'displayAnnotation("', id, '")')];
          onComplete:
                  (html jQuery ajax 
                       callback: [ :text | finalText := text ]
                       value: (html jQuery: #text) html)))

他のヒント

The XMLHttpRequest object has a onreadystatechange event. When the object reaches a readyState of 4, you can make your second AJAX request by binding an anonymous function to that event. If you want a more detailed response please post what you have tried and some code and the SO community will be more than willing to give you a more detailed answer.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top