You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Navigator在Flutter页面间传参时遭遇NoSuchMethodError错误

Flutter页面传参引发NoSuchMethodError的解决

错误信息

══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following NoSuchMethodError was thrown building edit(dirty, state: _editState#8e4e4):
'[]'
Dynamic call of null.
Receiver: Instance of 'document'
Arguments: ["content"]
The relevant error-causing widget was:
edit

问题场景

点击home.dart列表元素时,将自定义document对象传递到编辑器页面,期望打开对应的文档,但触发上述错误。

相关代码

Home.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:email_templating_app/pages/editor.dart';
import 'package:flutter/material.dart';

class document {
  final String name;
  final String content;
  final String id;

  document(this.name, this.content, this.id);
}

class home extends StatefulWidget {
  @override
  _homeState createState() => _homeState();
}

class _homeState extends State<home> {
  var db = FirebaseFirestore.instance;
  bool loading = true;
  late var templates = List<document>.empty(growable: true);
  
  Future<List<document>> getTemplates() async {
    List<document> templates = [];

    await db.collection("templates").get().then((querySnapshot) {
      querySnapshot.docs.forEach((result) {
        templates.add(document(
            result.data()["name"], result.data()["content"], result.id));
      });
    });

    return templates;
  }

  @override
  Widget build(BuildContext context) {
    if (loading) {
      getTemplates().then((value) {
        setState(() {
          templates = value;
        });
      });
      setState(() {
        loading = false;
      });
    }
    return Scaffold(
        appBar: AppBar(
          title: Text("Email Templates"),
        ),
        body: Center(
          child: ListView.builder(
              itemBuilder: (context, index) {
                return Card(
                  child: ListTile(
                    title: Text(templates[index].name),
                    onTap: () {
                      Navigator.push(
                          context,
                          MaterialPageRoute(
                            builder: (context) => edit(templates[index]),
                          ));
                    },
                  ),
                );
              },
              itemCount: templates.length),
        ));
  }
}

editor.dart

import 'dart:convert';

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:email_templating_app/pages/Home.dart';
import 'package:flutter/material.dart';
import 'package:super_editor/super_editor.dart';
import 'package:super_editor_unofficial_helper/super_editor_unofficial_helper.dart';

class edit extends StatefulWidget {
  final document doc;
  edit(this.doc);

  @override
  _editState createState() => _editState();
}

class _editState extends State<edit> {
  late MutableDocument myDoc;
  late DocumentEditor docEditor;
  FirebaseFirestore db = FirebaseFirestore.instance;

  MutableDocument createDocument(doc) {
    if (doc == null) {
      myDoc = MutableDocument(
        nodes: [
          ParagraphNode(
            id: DocumentEditor.createNodeId(),
            text: AttributedText(text: 'This is a header'),
            metadata: {
              'blockType': header1Attribution,
            },
          ),
          ParagraphNode(
            id: DocumentEditor.createNodeId(),
            text: AttributedText(text: 'This is the first paragraph'),
          ),
        ],
      );
      return myDoc;
    } else {
      myDoc = mapToDocument(json.decode(doc["content"]));
      return myDoc;
    }
  }

  @override
  Widget build(BuildContext context) {
    docEditor = DocumentEditor(document: createDocument(widget.doc));
    return Scaffold(
        appBar: AppBar(
          title: Text("Email Templates"),
        ),
        body: Center(
            child: SuperEditor(
          editor: docEditor,
        )),
        floatingActionButton: FloatingActionButton(
          onPressed: () async {
            await db
                .collection("templates")
                .doc(DateTime.now().toString())
                .set({
              "name": "test",
              "content": myDoc.toJson(),
            });
            print(myDoc.toJson());
          },
          child: Icon(Icons.save),
        ));
  }
}

错误原因及解决方案

核心错误

错误提示中Receiver: Instance of 'document'说明你在尝试用**下标访问([])**自定义document类的属性,但自定义类并不支持这种访问方式,必须通过类的成员变量直接访问。

修改步骤

  1. 修复属性访问方式
    在editor.dart的createDocument函数中,将doc["content"]改为doc.content:

    myDoc = mapToDocument(json.decode(doc.content));
    
  2. (可选)遵循Flutter命名规范
    Flutter中类名要求首字母大写,建议将document改为Document、home改为Home、edit改为Edit,避免与系统类混淆,同时提升代码可读性。

  3. 优化编辑器初始化逻辑
    当前在build方法中每次都会重新创建DocumentEditor,建议将初始化逻辑移到initState中,避免不必要的重复创建:

    @override
    void initState() {
      super.initState();
      myDoc = createDocument(widget.doc);
      docEditor = DocumentEditor(document: myDoc);
    }
    
    @override
    Widget build(BuildContext context) {
      return Scaffold(
          // ... 其余代码保持不变
      );
    }
    

后续扩展

解决传参问题后,你可以基于传递的document对象的id字段,实现Firestore中文档的更新功能,替换当前硬编码的保存逻辑。

内容的提问来源于stack exchange,提问作者Rowan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 10:02:12