agility icon indicating copy to clipboard operation
agility copied to clipboard

Feature Request: Event after model is ready

Open phonovision opened this issue 13 years ago • 7 comments

When the "create" event is fired the model seems to be not accessible yet. Some sort of "afterCreate" event would be useful in some cases.

I worked around this using a jQuery callback:

// [...]
controller:
            { 'create': function() {
                    //model not ready yet
                    //trigger jQuery-Callback $(...) when ready
                    that = this;
                    $(function() { that.trigger('change'); });
              },
              'change': function() {
                  ...
                                  ...
              } 
            }

phonovision avatar Sep 26 '11 09:09 phonovision

This could be related to #50

phonovision avatar Sep 28 '11 11:09 phonovision

I don't think it's documented yet, but the "afterCreate" event you're looking for is "post:create".

[...]
controller: {
  'create': function() {
    // create code
  },
  'post:create': function() {
    // "afterCreate" code
  }
}

Let me know if that meets your needs. ( the pull request implementing the feature is documented in #46 )

Cheers,

Tristan

tristanls avatar Oct 01 '11 01:10 tristanls

Hi Tristan, thanks for your answer!

"post:append' seems to nearly fit my needs. The model is ready but the controller doesn't wait until DOM ready. This can be solved (or worked around?) by using a jQuery callback:

//example: part of my jQuery-UI Tabs implementation
var tabContainer = $$({
    model:  { id:       'placeholder_tabcontainername'},
    view:   { format:   '<div data-bind="id id"><ul/></div>'},
    controller:
            { 'post:append': function() {  //bind jquery-ui tabs to div
                                        var tab = this.view.$();
                                        $(function () { tab.tabs(); });
              } 
            }
});

Although I would prefer not to delegate the "action" to a jQuery callback this is nicer and less hacky than my already mentioned work-around.

If you don't have a hint for a better solution you can close this issue. I'm satisfied with this solution. Thank you very much!

phonovision avatar Oct 03 '11 01:10 phonovision

Hmm...

I am curious because I was having a similar DOM related problem. Are you appending the tabContainer to $$.document later on, or are you appending it to some other widget, say: widget, which then itself is appended to $$.document? Something like:

var tabContainer = $$( ... );
var widget = $$( ... );
widget.append( tabContainer ); // will fire 'post:append'
$$.document.append( widget ); // will only fire 'post:append' on widget and not tabContainer

If the above is the case, then a possible solution could be some sort of propagation of the pre and post appended hooks, but I'm not clear how that would be done yet because we'd need to be able to tell the difference when it's appended to the DOM v. another agility object.

Having said that, the jQuery callback seems like a very useful workaround.

tristanls avatar Oct 03 '11 03:10 tristanls

Sorry if this example is a bit lengthy...

The MVC part:

// Tabs -----------------------------------------------------------------------
var tabContent = $$(    {   id:     'placeholder_id', content:'' }, 
                        '<div data-bind="content, id id"/>' );
var tab = $$({    //Tab header
    model:  { caption:  'placeholder_caption',
              ref:      'id_placeholder' },
    view:   { format:   '<li><a data-bind="caption, href ref"/></li>'}
});
var tabContainer = $$({
    model:  { id:       'placeholder_tabcontainername'},
    view:   { format:   '<div data-bind="id id"><ul/></div>'},
    controller:
            {  'post:append': function() {  //bind jquery-ui tabs to div
                                        var tab = this.view.$();
                                        $(function () { tab.tabs(); });
              } 
            }
});

Yes, the tabContainer is appended to an widget ( just a simple div container without special functionality till now). My usage:

// Container
tabs    = $$(tabContainer, {id:"tabs"});
aView.append(tabs);
// Header
tabA    = $$(tab, {caption:'Tab A', ref:'#tabA'});
tabB    = $$(tab, {caption:'Tab B', ref:'#tabB'});
tabs.append(tabA, 'ul');
tabs.append(tabB, 'ul');
// Content
tabAContent = $$(tabContent, {id:'tabA', content:'Just some simple text'});
tabBContent = $$(tabContent, {id:'tabB'}); //content retrieved by AJAX later on
tabs.append(tabAContent);
tabs.append(tabBContent);

Maybe the jQuery-UI Tabs are not the best example as they are a bit more complex and an "add"-method exists. But the "add"-method seems to do no magic and it is not available for an accordion for example.

phonovision avatar Oct 03 '11 17:10 phonovision

Thank you @6triple8 for the specific example. That seems to me to reinforce how the append is being fired currently and how it causes what you're seeing and having to rely on jQuery callback. Let's leave this open for now because it would be nice not to have to reach outside the framework for DOM-ready-dependent code.

tristanls avatar Oct 06 '11 04:10 tristanls

Yes, I agree with that. The workaround is usable but as it is somehow a "break" in the concept/encapsulation of agility it's more a fallback than a real solution.

If there is a better solution this would be great. Especially as there are probably some more users experiencing similar problems.

phonovision avatar Oct 07 '11 01:10 phonovision