重构时无法提取对封闭类方法的引用
Posted
技术标签:
【中文标题】重构时无法提取对封闭类方法的引用【英文标题】:Reference to an enclosing class method cannot be extracted on refactoring 【发布时间】:2020-04-25 10:53:36 【问题描述】:当我想做“提取到小部件”时,它会引发错误:“无法提取对封闭类方法的引用”
我知道有一些变量必须从类构造函数中获取它们的数据,但我希望 android Studio 提取小部件,然后我会纠正错误的代码,比如 Visual Studio 没有任何错误,然后将代码提取到新的小部件它需要将新提取的小部件复制到新的 dart 文件中并更正错误。
我想提取 Card 小部件部分。
import 'package:flutter/material.dart';
import 'package:flutter/material.dart' as prefix0;
import 'package:intl/intl.dart';
import '../model/transaction.dart';
class TransactionList extends StatelessWidget
final List<Transaction> transactions;
final Function deleteTx;
TransactionList(this.transactions, this.deleteTx);
@override
Widget build(BuildContext context)
return transactions.isEmpty
? LayoutBuilder(
builder: (ctx, constraint)
return Column(
children: <Widget>[
Text(
'There is no transaction',
style: Theme.of(context).textTheme.title,
textDirection: prefix0.TextDirection.rtl,
),
SizedBox(
height: 10,
),
Container(
height: constraint.maxHeight * 0.6,
child: Image.asset(
'assets/images/yalda.png',
fit: BoxFit.cover,
))
],
);
,
)
: ListView.builder(
itemCount: transactions.length,
itemBuilder: (ctx, index)
return **Card**(
margin: const EdgeInsets.symmetric(vertical: 8, horizontal: 5),
elevation: 5,
child: ListTile(
leading: CircleAvatar(
radius: 30,
child: Padding(
padding: const EdgeInsets.all(8),
child: FittedBox(
child: Text('\$$transactions[index].amount')),
),
),
title: Text(
transactions[index].title,
style: Theme.of(context).textTheme.title,
),
subtitle: Text(DateFormat.yMMMd()
.format(transactions[index].date)
.toString()),
trailing: MediaQuery.of(context).size.width > 360
? FlatButton.icon(
onPressed: () => deleteTx(transactions[index].id),
icon: const Icon(Icons.delete),
label: const Text('Delete'),
textColor: Theme.of(context).errorColor,
)
: IconButton(
icon: const Icon(Icons.delete),
color: Theme.of(context).errorColor,
onPressed: () => deleteTx(transactions[index].id),
),
),
);
);
【问题讨论】:
【参考方案1】:只需使用“提取方法”而不是“提取小部件”。 VSCode 将添加所有返回和引用。
编辑:如果您只想使用“提取小部件”,只需将该小部件包装在容器中,然后在该小部件上使用“提取小部件”。 如果这不起作用,请在小部件中注释掉 setState() 函数,然后重试。
【讨论】:
我们可以使用 Extract 方法或手动提取小部件,但是在使用提取方法或提取小部件时有什么约定吗?抱歉,我是 Flutter 的新手 :)【参考方案2】:您的 deleteTx 可能包含一个 setState(() ) 方法,请尝试注释您调用 deleteTx 的代码部分,并在提取后将其放回。
【讨论】:
【参考方案3】:我遇到了同样的问题,就我而言,这是因为 ListView.builder 和你一样。
所以很容易修复,只需在 Widget build 中创建一个类并返回 Card 并在 ListView.builder 中返回它TransactionList 类 带有所需的参数。
【讨论】:
【参考方案4】:你必须关心一些事情:
-
无论何时提取小部件,该小部件都不应包含当前工作页面中使用的任何变量。
所有函数或方法都应该是参数化的。
【讨论】:
【参考方案5】:这是因为您在 Card
小部件中从封闭类(即 TransactionList
)引用了一个变量(例如,transactions
)。在这种情况下,提取的最佳方法可能是在您的类之外创建无状态/有状态小部件并剪切 Card
小部件并将其粘贴为您创建的该小部件的构建方法的返回类型。您可以使用您创建的小部件的构造函数来引用这些变量。
【讨论】:
【参考方案6】:如果您可以注释掉代码中的“deleteTx(transactions[index].id)”部分,然后使用“onPressed: ()”,您将能够提取到小部件。提取后可以使用 onPressed: ()setState(() deleteTx(transactions[index].id););
【讨论】:
【参考方案7】:当前类中的变量可能存在一些局部引用,因此如果存在一些引用,我们无法从那里提取小部件。
【讨论】:
【参考方案8】:将 onpressed 等属性转换为 cmets,然后重试“提取小部件”并继续
【讨论】:
【参考方案9】:您可以使用“提取方法”。这是一个简单的方法。 VSCode 将添加所有返回和引用。
【讨论】:
以上是关于重构时无法提取对封闭类方法的引用的主要内容,如果未能解决你的问题,请参考以下文章