[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/webroot/rsrc/externals/javelin/ext/view/ -> ViewPlaceholder.js (source)

   1  /**
   2   * Initialize a client-side view from the server. The main idea here is to
   3   * give server-side views a way to integrate with client-side views.
   4   *
   5   * The idea is that a client-side view will have an accompanying
   6   * thin server-side component. The server-side component renders a placeholder
   7   * element in the document, and then it will invoke this  behavior to initialize
   8   * the view into the placeholder.
   9   *
  10   * Because server-side views may be nested, we need to add complexity to
  11   * handle nesting properly.
  12   *
  13   * Assuming a server-side view design that looks like hierarchical views,
  14   * we have to handle structures like
  15   *
  16   * <server:component>
  17   *   <client:component id="1">
  18   *     <server:component>
  19   *       <client:component id="2">
  20   *       </client:component>
  21   *     </server:component>
  22   *   </client:component>
  23   * </server:component>
  24   *
  25   * This leads to a problem: Client component 1 needs to initialize the behavior
  26   * with its children, which includes client component 2. So client component
  27   * 2 must be rendered first. When client component 2 is rendered, it will also
  28   * initialize a copy of this behavior. If behaviors are run in the order they
  29   * are initialized, the child component will run before the parent, and its
  30   * placeholder won't exist yet.
  31   *
  32   * To solve this problem, placeholder behaviors are initialized with the token
  33   * of a containing view that must be rendered first (if any) and a token
  34   * representing it for its own children to depend on. This means the server code
  35   * is free to call initBehavior in any order.
  36   *
  37   * In Phabricator, AphrontJavelinView demonstrates how to handle this correctly.
  38   *
  39   * config: {
  40   *   id: Node id to replace.
  41   *   view: class of view, without the 'JX.' prefix.
  42   *   params: view parameters
  43   *   children: messy and loud, cute when drunk
  44   *   trigger_id: id of containing view that must be rendered first
  45   * }
  46   *
  47   * @provides javelin-behavior-view-placeholder
  48   * @requires javelin-behavior
  49   *           javelin-dom
  50   *           javelin-view-renderer
  51   *           javelin-install
  52   */
  53  
  54  
  55  
  56  JX.behavior('view-placeholder', function(config, statics) {
  57    JX.ViewPlaceholder.register(config.trigger_id, config.id, function() {
  58      var replace = JX.$(config.id);
  59  
  60      var children = config.children;
  61      if (typeof children === "string") {
  62        children = JX.$H(children);
  63      }
  64  
  65      var view = new JX[config.view](config.params, children);
  66      var rendered = JX.ViewRenderer.render(view);
  67  
  68      JX.DOM.replace(replace, rendered);
  69    });
  70  });
  71  
  72  JX.install('ViewPlaceholder', {
  73    statics: {
  74      register: function(wait_on_token, token, cb) {
  75        var ready_q = [];
  76        var waiting;
  77  
  78        if (!wait_on_token || wait_on_token in JX.ViewPlaceholder.ready) {
  79          ready_q.push({token: token, cb: cb});
  80        } else {
  81          waiting = JX.ViewPlaceholder.waiting;
  82          waiting[wait_on_token] = waiting[wait_on_token] || [];
  83          waiting[wait_on_token].push({token: token, cb: cb});
  84        }
  85  
  86        while(ready_q.length) {
  87          var ready = ready_q.shift();
  88  
  89          waiting = JX.ViewPlaceholder.waiting[ready.token];
  90          if (waiting) {
  91            for (var ii = 0; ii < waiting.length; ii++) {
  92              ready_q.push(waiting[ii]);
  93            }
  94            delete JX.ViewPlaceholder.waiting[ready.token];
  95          }
  96          ready.cb();
  97  
  98          JX.ViewPlaceholder.ready[token] = true;
  99        }
 100  
 101      },
 102      ready: {},
 103      waiting: {}
 104    }
 105  });


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1