簡體   English   中英

在 Ember 中為 ember-i18n 動態渲染組件

[英]Dynamically render components in Ember for ember-i18n

首先,在這種情況下,ember 的組件助手沒有幫助。 只有當我知道需要渲染多少個組件以及以什么順序渲染時,這才會有所幫助。

我需要能夠基於如下字符串呈現組件:
{{user}} has made a bid of {{bid}} ,其中:

  1. {{user}}{{bid}}將被組件替換。
  2. 給定的字符串是未知的,代表組件的動態部分數量未知(組件將與給定的字符串一起傳入)。

如果這些動態部分是助手,這將很容易 - 但助手只是不會為我的游戲中的某些項目削減它。

理想情況下,我可以做這樣的事情:

{{translated-content
  content='{{user}} has made a bid of {{bid}}'
  user=(component 'user-ui')
  bid=(component 'bid-ui') }}

這可能與 ember 一起使用嗎?

在一些幫助下,我想出了以下可與 ember-i18n 和 ember 1.11 或更高版本一起使用的組件。

它可能會進一步優化,但它的工作方式很好,速度也很快。

創建一個新組件

ember g component tt

模板.hbs

{{#each parts as |part|}}

  {{#if part.isComponent}}
    {{component part.content}}
  {{else}}
    {{part.content}}
  {{/if}}

{{/each}}

組件.js

import Ember from 'ember';
const { $ } = Ember;

export default Ember.Component.extend({

  tagName: 'span',

  updateComponents: Ember.on('didReceiveAttrs',function(opts){

    let newAttrs = opts.newAttrs;
    let components = {};

    $.each(newAttrs,(key,val)=>{

      if( key !== 't' && typeof val === 'object' ){
        let keys = Object.keys(val);
        if(keys.length && keys[0].indexOf('COMPONENT_')>=0){
          components[key] = val;
        }
      }

    });

    this.set('_components',components);

  }),

  parts: Ember.computed('_components','t','i18n.locale',function(){

    let attrs = [];
    let components = this.get('_components');
    let componentKeys = Object.keys(components);

    $.each(this.attrs,(key,val)=>{
      if( key !== 't'){
        if( componentKeys.indexOf(key)<0 ){
          attrs[key] = val;
        } else {
          attrs[key] = `{{${key}}}`;
        }
      }
    });

    let content = this.get('i18n').t(this.get('t'),attrs).toString();
    content = content.replace(/\{\{(\w+?)\}\}/g,(fullMatch)=>{
      return `{{split}}${fullMatch}{{split}}`;
    });

    let parts = content.split('{{split}}');

    parts.forEach((val,i)=>{
      let isComponent;
      let key = val.replace(/\{\{(\w+?)\}\}/g,(fullMatch,key)=>{
        isComponent = true;
        return key;
      });

      if(isComponent && components[key]){
        parts[i] = {
          isComponent: true,
          content: components[key]
        };
      } else {
        parts[i] = {
          content: Ember.String.htmlSafe(val)
        };
      }

    });

    return parts;

  }),

}).reopenClass({
  positionalParams: ['t']
});

用法

{{t-t
  'your-ember-i18n-path'
  key1='Normal Content (example)'
  key2=(component 'your-component') }}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM