【问题标题】:How to convert an object to array (map) in Dart?如何在 Dart 中将对象转换为数组(映射)?
【发布时间】:2015-02-08 22:32:48
【问题描述】:

如何在 Dart 中将 Object 类型转换为 Map 类型(数组),使变量成为键/值对?

【问题讨论】:

    标签: arrays object reflection dart type-conversion


    【解决方案1】:
    /**
       * Uses refection (mirrors) to produce a Map (array) from an object's
       * variables. Making the variable name the key, and it's value the
       * value.
       */
      Map objectToMap(Object object)
      {
        // Mirror the particular instance (rather than the class itself)
        InstanceMirror instanceMirror = reflect(object);
        Map dataMapped = new Map();
    
        // Mirror the instance's class (type) to get the declarations
        for (var declaration in instanceMirror.type.declarations.values)
        {
          // If declaration is a type of variable, map variable name and value
          if (declaration is VariableMirror)
          {
            String variableName = MirrorSystem.getName(declaration.simpleName);
            String variableValue = instanceMirror.getField(declaration.simpleName).reflectee;
    
            dataMapped[variableName] = variableValue;
          }
        }
    
        return dataMapped;
      }
    

    【讨论】:

    • 请注意,这对于服务器端代码是可以的,但不建议使用带有 dart2js 的镜像。 smoke 包可以帮助解决这个用例。它在 Dartium 中运行时使用镜像,但在 dart2js 中运行时使用代码生成。
    【解决方案2】:

    将递归地将任何 JS 对象转换为 Dart 映射、列表或标量值:

    /// js_interop.dart
    import 'dart:js';
    
    /// Converts the specified JavaScript [value] to a Dart instance.
    dynamic convertToDart(value) {
      // Value types.
      if (value == null) return null;
      if (value is bool || value is num || value is DateTime || value is String) return value;
    
      // JsArray.
      if (value is Iterable) return value.map(convertToDart).toList();
    
      // JsObject.
      return new Map.fromIterable(getKeysOfObject(value), value: (key) => convertToDart(value[key]));
    }
    
    /// Gets the enumerable properties of the specified JavaScript [object].
    List<String> getKeysOfObject(JsObject object) => (context['Object'] as JsFunction).callMethod('keys', [object]);
    

    用法:

    /// config.js
    window.$environment = 'staging';
    window.$config = {
      name: 'FooBar',
      params: {
        assets: ['css', 'js'],
        forceSsl: true
      }
    };
    
    /// main.dart
    import 'dart:js' as js;
    import 'js_interop.dart';
    
    void main() {
      var environment = convertToDart(js.context[r'$environment']);
      assert(environment is String);
      assert(environment == 'staging');
    
      var config = convertToDart(js.context[r'$config']);
      assert(config is Map<String, dynamic>);
      assert(config.length == 2);
    
      assert(config['name'] is String);
      assert(config['name'] == 'FooBar');
    
      assert(config['params'] is Map<String, dynamic>);
      assert(config['params'].length == 2);
    
      assert(config['params']['forceSsl'] is bool);
      assert(config['params']['forceSsl'] == true);
    
      assert(config['params']['assets'] is List<String>);
      assert(config['params']['assets'].length == 2);
      assert(config['params']['assets'].first == 'css');
      assert(config['params']['assets'].last == 'js');
    }
    

    注意事项:创建的实例不反映原始 JS 对象的更改。如果您需要此功能,请参阅:https://stackoverflow.com/a/20720378/1084485

    【讨论】:

      猜你喜欢
      • 2019-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-23
      相关资源
      最近更新 更多