如何动态解析 Ractive.js 模板中使用的键路径列表

How to dynamically parse a list of keypaths used within a Ractive.js template(s)

本文关键字:列表 路径 js 何动态 动态 Ractive      更新时间:2023-09-26

是否可以解析出动态部分/组件使用的键路径列表?

如果我从一个完全空的数据对象开始 - 并动态添加一个部分/组件。可以逐步执行动态添加的部分的 html 并发现使用了哪些键路径。

我的目的是将此键路径列表动态应用于我的数据对象。我正在构建一个拖放所见即所得的 UI - 并希望设计师能够在不接触活动的情况下添加模板......

这里有一些伪代码,我希望能说明我想要实现的目标。

<script id="foo" type="text/ractive">
   <p>{{blah}}</p>
   <p>{{blahblah}}</p>
</script>

-

var ractive = new Ractive({
  el: '#container',
  template: '{{#items}}{{partial}}{{/items}}',
  data: {
      items : [] // empty to start with
  }
});

ractive.on( 'addpartial', function ( event ) {
  // partial gets added
    // process the partial to find out what keypaths it contains.. put those keypaths into  array
var partialDataArray = [{'blah':''},{'blahblah':''}]
    this.push('items' , { 'partial' : 'foo', partialDataArray }
});

另一种选择是将每个"部分"设置为一个组件 - 但我会重复自己的负载(我正在尝试全部 DRY 等(

干杯抢

这段代码大量借鉴了 Martydpx https://github.com/martypdx 给出的动态组件示例 - 尽管我找不到找到它的帖子。

创建了一个设置函数,基本上可以为我解析所有内容。这意味着我可以提供一个包含一长串模板的文件(供组件使用(

<div data-component="first_component">
      <h1>{{h1}}</h1>
      <p>{{p1}}</p>
</div>
<div data-component="second_component">
      <p>{{p1}}</p>
</div>

-- 这是 JS。编辑 - 请参阅 JavaScript 正则表达式 - 从无限数量的大括号中获取字符串以获得正确的正则表达式。

var htmlSnippets = [];
var setup = function() {
  // load in our ractive templates - each one is wrapped in a div with
  // a data attribute of component.
  $.get("assets/snippets/snippets2.htm", function(data) {
    var snippets = $.parseHTML(data);
    // Each over each 'snippet / component template' parsing it out.
    $.each(snippets, function(i, el) {
      if ($(el).attr('data-component')) {
        var componentName = $(el).attr('data-component')
        // reg ex to look for curly braces {{ }} - used to get the names of each keypath
        var re = /[^{]+(?=}})/g;
        // returns an array containing each keypath within the snippet nb: ['foo' , 'bar']
        var componentData = $(el).html().match(re); 
        // this is probably a bit messy... adding a value to each keypath...
        // this returns an array of objects.
        componentData = $.map( componentData, function( value ) {
            return { [value] : 'Lorem ipsum dolor sit amet' };
        });
        // combine that array of objects - so its a single data object
        componentData = componentData.reduce(function(result, currentObject) {
          for(var key in currentObject) {
              if (currentObject.hasOwnProperty(key)) {
                  result[key] = currentObject[key];
              }
          }
          return result;
        }, {});
        // and add the component name to this data object
        componentData['componentName'] = componentName;
        // We need to use the data elsewhere - so hold it here...
        htmlSnippets.push(componentData );
        // and lastly set our component up using the html snippet as the template
        Ractive.components[componentName] = Ractive.extend({
            template: $(el).html()
        });
      }
    });
    Ractive.components.dynamic = Ractive.extend({
        template: '<impl/>',
        components: {
            impl: function(){
                return this.components[this.get('type')]
            }
        }
    });
  });
}();

var ractive = new Ractive({
  el: '#container',
  template: '#template',
  data: {
    widgets: htmlSnippets, 
    pageContent: []
  }
});