【问题标题】:How create a interface (class) in Dart for an nested Map如何在 Dart 中为嵌套 Map 创建接口(类)
【发布时间】:2020-11-04 18:15:31
【问题描述】:

在我的 Flutter 应用中,我收到带有自定义负载的通知,例如:

{ notification: 
  { 
    title: Test, 
    body: AAAA 
  }, 
  data: 
  { 
    productId: Axe, 
    page: Products, 
    click_action: FLUTTER_NOTIFICATION_CLICK
  }
}

一切正常。我还可以通过以下方式访问通知的有效负载: message['data']['page']

但我更愿意使用接口/类来按键命名数据,例如: message.data.pagemessage.data.productId

所以我尝试了:

class NotificationMessage {
  Map notification;
  Map data;

  NotificationMessage(this.notification, this.data);
}

...
NotificationMessage _message = message; // Assigning the payload to the final
...

这是我卡住的地方:这里出现错误:“Map”类型的值不能分配给“NotificationMessage”类型的变量。

我的课还没有结束,但是如何继续? 我知道 json_serializable,但在任何工具之前,我想完全理解它。

【问题讨论】:

  • 您的自定义对象需要在键周围加上引号,这样您就可以针对不同的实例使用构建器方法。我将根据有效负载/对象是 json 的假设写一个答案。

标签: flutter dart


【解决方案1】:

首先,您需要构建通知和数据的两个模型,如下所示

class DataMessage {
  final String productId;

  final String page;

  final String click_action;

  DataMessage(this.productId, this.page, this.click_action);

  factory DataMessage.fromJson(Map<dynamic, dynamic> json) {
    return DataMessage(
      json['productId'] as String,
      json['page'] as String,
      json['click_action'] as String,
    );
  }
} 

class NotificationMessage {
  final String title;

  final String body;

  NotificationMessage(this.title, this.body);
  factory NotificationMessage.fromJson(Map<dynamic, dynamic> json) {
    return NotificationMessage(
      json['title'] as String,
      json['body'] as String,
    );
  }
}

工厂方法将地图类型转换为模型类。

那么你必须为响应消息建立一个模型,如下所示

class Message {
  final NotificationMessage notification;
  final DataMessage data;

  Message(this.notification, this.data);
  factory Message.fromJson(Map<dynamic, dynamic> json) {
    final Map<dynamic, dynamic> mapNotification = json['notification'];
    final Map<dynamic, dynamic> mapData = json['data'];
    
    final dataModel = DataMessage.fromJson(mapData);
    final notificationModel = NotificationMessage.fromJson(mapNotification);
    
    return Message(
      notificationModel as NotificationMessage,
      dataModel as DataMessage,
    );
  }
}

请注意,工厂方法允许您将每个模型的映射转换为类模型

所以你可以将你的响应定义为一个类

Map<dynamic, dynamic> messageResponse = {
  'notification': {'title': 'Test', 'body': 'AAAA'},
  'data': {
    'productId': 'Axe',
    'page': 'Products',
    'click_action': 'FLUTTER_NOTIFICATION_CLICK'
  }
};

final Message message = Message.fromJson(messageResponse);
  print(message.data.productId);
  print(message.data.page);
  print(message.data.click_action);
  
  print(message.notification.title);
  print(message.notification.body);

希望对你有帮助

【讨论】:

    【解决方案2】:

    json 对象的实例。这样你就可以在不修改类的情况下为任何实例使用地图

    { "notification": 
      { 
        "title": "Test", 
        "body": "AAAA" 
      }, 
      "data": 
      { 
        "productId": "Axe", 
        "page": "Products", 
        "click_action": "FLUTTER_NOTIFICATION_CLICK"
      }
    }
    

    类的样子;

    class NotificationMessage {
    NotificationMessage({
        this.notification,
        this.data,
    });
    
    final Notification notification;
    final Data data;
    
    factory NotificationMessage.fromJson(Map<String, dynamic> json) => NotificationMessage(
        notification: Notification.fromJson(json["notification"]),
        data: Data.fromJson(json["data"]),
    );
    
    Map<String, dynamic> toJson() => {
        "notification": notification.toJson(),
        "data": data.toJson(),
    };
    }
    
    class Data {
    Data({
        this.productId,
        this.page,
        this.clickAction,
    });
    
    final String productId;
    final String page;
    final String clickAction;
    
    factory Data.fromJson(Map<String, dynamic> json) => Data(
        productId: json["productId"],
        page: json["page"],
        clickAction: json["click_action"],
    );
    
    Map<String, dynamic> toJson() => {
        "productId": productId,
        "page": page,
        "click_action": clickAction,
    };
    }
    
    class Notification {
    Notification({
        this.title,
        this.body,
    });
    
    final String title;
    final String body;
    
    factory Notification.fromJson(Map<String, dynamic> json) => Notification(
        title: json["title"],
        body: json["body"],
    );
    
    Map<String, dynamic> toJson() => {
        "title": title,
        "body": body,
    };
    }
    

    要构建的函数

    Future<NotificationMessage> getNotf() {
          var parsedJson = json.decode(//your received object);
      return NotificationMessage.fromJson(parsedJson);
    
    }
    

    现在您可以在诸如

    的构建器中接收它
     _futureNotifications =Future<NotificationMessage>
    
       _futureNotifications = getNotf(); //this is a function and can be used after a gesture or initState
        FutureBuilder<NotificationMessage>(
                future: _futureNotifications,
                builder: (context, snapshot) {
                   }
    

    【讨论】:

      猜你喜欢
      • 2021-11-25
      • 2018-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-13
      • 2021-06-25
      • 2016-01-17
      相关资源
      最近更新 更多