Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Run time consuming functions before removing snippets ( teardown phase ) #34

Open
yess-webioza opened this issue Oct 31, 2018 · 4 comments

Comments

@yess-webioza
Copy link

Hi, i have another question.

Is there a way to suspend execution of functions after teardown of some snippet or before-update event until actions are done in mentioned functions?

For example i have this code:

var PluginInitializer = _context.extend(function(page, snippetManager) {

        this._ = {
            page: page,
            snippetManager: snippetManager
        };

        this._.snippetManager.on('before-update', this._beforeUpdate.bind(this));
        this._.snippetManager.on('after-update', this._afterUpdate.bind(this));

    }, {
   _beforeUpdate: function(changeset) {
   // run modal closing animation
   // need to wait for execute animation. After that continue with snippet removal
  }
  });

so i need to wait for animation to be done before modal snippet is removed. I'm using standard bootstrap modal. I'm automatically opening modal after it is added to DOM in _afterUpdate function

@jahudka
Copy link
Member

jahudka commented Oct 31, 2018

Hi, yes there is, but not using the standard before-update / after-update events or the setup / teardown callbacks of snippets - these are synchronous and you cannot alter the transaction sequence from within them. You need to set up a so-called transaction agent - that's a service which listens to the transaction-created event of the page service and then manipulates each transaction separately.

Each transaction will emit the dispatch event, plus a number of other agent-specific events; these events typically occur before the action they are tied to is performed and they are usually asynchronous, meaning you can call evt.waitFor(<promise>) to postpone the event's resolution and the associated action until an arbitrary promise resolves.

As an example the transaction itself has an internal Promise whose fulfillment is tied to the dispatch event in this manner - when the dispatch event is no longer waiting for any Promises, the transaction is fulfilled (which is when the 'in' animations are applied and an entry is saved to the browser history stack). Another example is the snippets-apply event emitted on the transaction by the snippet agent - the agent makes the transaction wait for the snippets-apply event, which in turn is used by the transition agent to postpone applying snippets until the 'out' transition has completed.

So ultimately what you want to do is make at least the transition's dispatch event wait until your modal is closed; but to avoid snippets being applied while the modal is still at least partially open the snippets-apply event might be a better choice. You may or may not need to listen to other events (like ajax-response) in order for your logic to determine whether the modal should or should not be closed. Assuming the simplest scenario ("close the dialog as soon as snippet X is to be updated") you could do something like this:

var PluginInitializer = _context.extend(function(page) {
    this._ = {
        page: page
    };

    this._.page.on('transaction-created', this._handleTransaction.bind(this));
}, {
    _handleTransaction: function(evt) {
        evt.data.transaction.on('snippets-apply', this._handleSnippets.bind(this));
    },
    _handleSnippets: function(evt) {
        var snippetId = 'snippet--modal',
            changeset = evt.data.changeset;

        if (snippetId in changeset.add || snippetId in changeset.update || snippetId in changeset.remove) {
            // if the snippet id we're watching for appears in the changeset,
            // we tell the snippet agent to wait until the modal is closed
            // before actually applying the snippets and allowing the transaction
            // to be resolved
            evt.waitFor(this._closeModal());
        }
    },
    _closeModal: function() {
        return new Promise(function(fulfill) {
            // ...
        });
    }
});

@jahudka
Copy link
Member

jahudka commented Oct 31, 2018

Btw, for future reference, Nittro now has a forum where you can ask questions, no need to abuse Github Issues ;-)

@jahudka
Copy link
Member

jahudka commented Oct 31, 2018

You can check the code of the various transaction agents that Nittro itself uses to give you an idea of what's possible and how it works - check out the Page component's repository

@yess-webioza
Copy link
Author

Oh great! .. thanks a lot

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants