[wp-trac] [WordPress Trac] #38889: Proposition to allow an api.Value() using asynchronous callbacks

WordPress Trac noreply at wordpress.org
Mon Nov 21 23:29:43 UTC 2016


#38889: Proposition to allow an api.Value() using asynchronous callbacks
-------------------------------+------------------------------
 Reporter:  nikeo              |       Owner:
     Type:  enhancement        |      Status:  new
 Priority:  normal             |   Milestone:  Awaiting Review
Component:  Customize          |     Version:  trunk
 Severity:  normal             |  Resolution:
 Keywords:  reporter-feedback  |     Focuses:  javascript
-------------------------------+------------------------------

Comment (by westonruter):

 @nikeo For the specific use case of lazy-loading things for performance,
 there is also #28580.

 Also, the performance of nav menu is improved specifically by deferring
 the embedding of `nav_menu_item` controls until the parent section is
 expanded. The same is also now being done for widgets. See:
 https://core.trac.wordpress.org/browser/tags/4.6.1/src/wp-admin/js
 /customize-nav-menus.js#L1023
 https://core.trac.wordpress.org/browser/tags/4.6.1/src/wp-admin/js
 /customize-widgets.js#L446

 Both of these examples however have all of the controls exported from PHP
 up-front. There's no lazy-loading yet of the controls. The
 [https://github.com/xwp/wp-customize-posts Customize Posts] plugin,
 however, ''does'' lazy-load sections for posts and all of the controls for
 post fields and postmeta.

 I think your use case can currently be satisfied well enough with the
 current API. Namely:

 1. You expand a section and this triggers an Ajax request to fetch the
 items (e.g. nav menu items) that would be contained within it.
 2. The Ajax request returns with the list of the items and you generate
 the IDs for the controls, e.g. `nav_menu_item[123]`.
 3. Given the list of control IDs (`controlIds`), you create a deferred
 callback for when they are all created.
 4. Given the created controls, you can pluck out the `embedded` deferred
 from each.

 In the end, it could look something like this using current customizer JS:

 {{{#!js
 (function ( api, $ ) {
         var fooSectionPopulated, populateFooSectionControls;

         fooSectionPopulated = $.Deferred();

         populateFooSectionControls = function( section ) {
                 wp.ajax.send( 'list_bar_items' ).done( function( items ) {
                         var settingIds = [], controlIds = [];
                         /* ... create settings ... */
                         /* ... create controls and set section param to
 section.id ... */

                         // This isn't really necessary because the
 controls were just created above.
                         api.control.apply( api.control, controlIds.concat(
 function() {
                                 var controlEmbeddeds = [];
                                 _.each( arguments, function( control ) {
                                         controlEmbeddeds.push(
 control.deferred.embedded );
                                 } );

                                 $.when( controlEmbeddeds ).done(
 function() {
                                         fooSectionPopulated.resolve(
 section );
                                 } );
                         } ) )
                 } ).fail( function() {
                         fooSectionPopulated.reject();
                 } );
         };

         // Lazy-load the controls into section foo when it is expanded.
         api.section( 'foo', function populateSection( section ) {
                 var onceExpanded;
                 if ( section.expanded() ) {
                         populateFooSectionControls( section );
                 } else {
                         onceExpanded = function( isExpanded ) {
                                 if ( isExpanded ) {
                                         section.expanded.unbind(
 onceExpanded );
                                         populateFooSectionControls(
 section );
                                 }
                         };
                         section.expanded.unbind( onceExpanded );
                 }
         } );
 }) ( wp.customize, jQuery );
 }}}

 Naturally this can be generalized into a more reusable bit of code. I'm
 not sure `wp.customize.Value` should be turned into a deferred object
 itself.

--
Ticket URL: <https://core.trac.wordpress.org/ticket/38889#comment:4>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list