Flutter: 在 dart 代码中考虑类似 JSX 的语法

创建于 2017-08-14  ·  238评论  ·  资料来源: flutter/flutter

如果除了当前构建小部件的方式之外,您还可以添加类似 JSX 的功能,那就太好了。 我的意思是添加微小的语法糖以在 dart 代码中启用类似 XML 的结构。 它只是让代码更容易阅读/开发/调试/维护,也让强大的 GUI 构建器更容易与可编辑代码集成。

寻找类似 DSX 的东西:
https://spark-heroku-dsx.herokuapp.com/index.html

卡洛斯。


DSX 当前的问题是与 Flutter 工具的正确集成,以便为 .dsx 文件上的调试器、自动完成等提供出色的开发人员体验。

告诉用户他们可以使用 DSX 但不能使用调试器或享受自动完成功能对我来说是行不通的。 如果有人想提供帮助,我需要想办法为 Dart 工具和 VS Code Dart 插件添加完整的预处理支持(带有源映射)。一旦工具支持 DSX 或任何其他转译语言(任何语言是 Dart 的超集,但将所有内容都编译为 Dart)就可以了。

如果您可以并且愿意提供帮助,请告诉我。

dart engine framework

最有用的评论

好的,所以“ https://flutter.io/widgets-intro/#basic -widgets”上的“基本小部件”示例如下所示:

import 'package:flutter/material.dart';

class MyAppBar extends StatelessWidget {
  MyAppBar({this.title});

  // Fields in a Widget subclass are always marked "final".

  final Widget title;

  <strong i="7">@override</strong>
  Widget build(BuildContext context) {
    let style = {
        height: 56.0, // in logical pixels
        padding: const EdgeInsets.symmetric(horizontal: 8.0),
        decoration: <BoxDecoration color={Colors.blue[500]}/>,
    };

    return <Container style={style}>
      <Row>
        <IconButton
            icon={<Icon name={Icons.menu}/>}
            tooltip='Navigation menu'
            onPressed={null}
        />
        <Expanded>
           {title}
    </Expanded>  
        <IconButton
            icon={<Icon name={Icons.search}/>}
            tooltip='Search'
            onPressed={null}
        />
      </Row>
    </Container>;
  }
}

class MyScaffold extends StatelessWidget {
  <strong i="8">@override</strong>
  Widget build(BuildContext context) {
    // Material is a conceptual piece of paper on which the UI appears.
    return <Material>
      <Column>
          <MyAppBar
             title={<Text 
               text='Example title'
               style={Theme.of(context).primaryTextTheme.title},
             />}
          />
          <Expanded>
            <Center>
              <Text text='Hello, world!'/>
            </Center>
          </Expanded>
      </Column>
    </Material>;
  }
}

void main() {
  runApp(<MaterialApp
    title='My app'
    home={<MyScaffold/>}
  />);
}

所有238条评论

抄送@lukechurch

@cbazza你能详细说明你为什么想要这个吗? 也许展示一个与今天相比会是什么样子的例子?

好的,所以“ https://flutter.io/widgets-intro/#basic -widgets”上的“基本小部件”示例如下所示:

import 'package:flutter/material.dart';

class MyAppBar extends StatelessWidget {
  MyAppBar({this.title});

  // Fields in a Widget subclass are always marked "final".

  final Widget title;

  <strong i="7">@override</strong>
  Widget build(BuildContext context) {
    let style = {
        height: 56.0, // in logical pixels
        padding: const EdgeInsets.symmetric(horizontal: 8.0),
        decoration: <BoxDecoration color={Colors.blue[500]}/>,
    };

    return <Container style={style}>
      <Row>
        <IconButton
            icon={<Icon name={Icons.menu}/>}
            tooltip='Navigation menu'
            onPressed={null}
        />
        <Expanded>
           {title}
    </Expanded>  
        <IconButton
            icon={<Icon name={Icons.search}/>}
            tooltip='Search'
            onPressed={null}
        />
      </Row>
    </Container>;
  }
}

class MyScaffold extends StatelessWidget {
  <strong i="8">@override</strong>
  Widget build(BuildContext context) {
    // Material is a conceptual piece of paper on which the UI appears.
    return <Material>
      <Column>
          <MyAppBar
             title={<Text 
               text='Example title'
               style={Theme.of(context).primaryTextTheme.title},
             />}
          />
          <Expanded>
            <Center>
              <Text text='Hello, world!'/>
            </Center>
          </Expanded>
      </Column>
    </Material>;
  }
}

void main() {
  runApp(<MaterialApp
    title='My app'
    home={<MyScaffold/>}
  />);
}

这个语法怎么样?:

import 'package:flutter/material.dart';

class MyAppBar extends StatelessWidget {
  MyAppBar({this.title});

  // Fields in a Widget subclass are always marked "final".

  final Widget title;

  <strong i="6">@override</strong>
  Widget build(BuildContext context) {
    return Container(
      height: 56.0, // in logical pixels
      padding: EdgeInsets.symmetric(horizontal: 8.0),
      decoration: BoxDecoration(color: Colors.blue[500]),
      child: Row(
        children: <Widget>[
          IconButton(
            icon: Icon(Icons.menu),
            tooltip: 'Navigation menu',
            onPressed: null,
          ),
          Expanded(
            child: title,
          ),
          IconButton(
            icon: Icon(Icons.search),
            tooltip: 'Search',
            onPressed: null,
          ),
        ],
      ),
    );
  }
}

class MyScaffold extends StatelessWidget {
  <strong i="7">@override</strong>
  Widget build(BuildContext context) {
    // Material is a conceptual piece of paper on which the UI appears.
    return Material(
      child: Column(
        children: <Widget>[
          MyAppBar(
            title: Text(
              'Example title',
              style: Theme.of(context).primaryTextTheme.title,
            ),
          ),
          Expanded(
            child: Center(
              child: Text('Hello, world!'),
            ),
          ),
        ],
      ),
    );
  }
}

void main() {
  runApp(MaterialApp(
    title: 'My app',
    home: MyScaffold(),
  ));
}

Huumm,有一点改进,但​​不是那么好......
以下是使用 XML 完成的事情:
(1) 不再有“孩子”和“孩子”的东西
(2) 便于 3rd 方工具操作(解析、分析和重新生成)
(3) 注意标记和编程之间的切换很容易被检测到。 我的意思是在 XML 中你有'{}'来分隔代码,而在代码中你有' 还将所有“风格”的东西与主要结构分开。
我知道这基本上完全支持 React 的方式,但无论如何你已经完成了一半;)

抄送@kasperl

(1) 不再有“孩子”和“孩子”的东西

我真的不明白为什么这是可取的。 “child”和“children”并不特别。 以 ListTile 为例。 你会怎么做呢? 为什么 IconButton 中的“icon”或 MaterialApp 中的“home”是您想要命名的东西,而不是 Expanded 中的“child”? 这三个只是碰巧采用 Widget 对象的任意参数。 “孩子”与“家”并没有什么神奇之处。

(2) 便于 3rd 方工具操作(解析、分析和重新生成)

您可以解析、分析和重新生成 Dart 代码。 但我同意我们应该让这更容易。 希望在未来几年 Dart 团队会为此提供更好的 API。

(3) 注意标记和编程之间的切换很容易被检测到。

为什么这是可取的? 我的意思是,为什么这些都算作“编程”? 一切都只是表达。

我的意思是在 XML 中你有'{}'来分隔代码,而在代码中你有'

我真的不明白其中的区别。

还将所有“风格”的东西与主要结构分开。

如果你真的想的话,你现在可以在 Flutter 中做到这一点,只需像在 XML 案例中那样将样式放在一个变量中。

我真的不明白为什么这是可取的。 “child”和“children”并不特别。 以 ListTile 为例。 你会怎么做呢? 为什么 IconButton 中的“icon”或 MaterialApp 中的“home”是您想要命名的东西,而不是 Expanded 中的“child”? 这三个只是碰巧采用 Widget 对象的任意参数。 “孩子”与“家”并没有什么神奇之处。

少一点样板,就不用说了,因为在结构上是继承的。

为什么这是可取的? 我的意思是,为什么这些都算作“编程”? 一切都只是表达。

它与 (2) 相关,因为它使工具制造者,特别是 GUI 构建者的生活变得更加容易,因为他们不需要完全解析 Dart; 但它也使阅读代码更容易。

我真的不明白其中的区别。

XML 的格式非常简单,所以当您看到“{}”时,您就知道它正在计算 dart 中的表达式。 反之亦然,当阅读飞镖代码时,你会看到 ') 您知道对象层次结构是从 XML 标记创建的。

同样在最终的 XML 处理器中,我会避​​免将对象传递给父母的属性,而是创建子标签,如下所示:

this...
          <MyAppBar>
             <Title style={Theme.of(context).primaryTextTheme.title}>  
                 Example title
             </Title>
          </MyAppBar>

instead of this...
          <MyAppBar
             title={<Text 
               text='Example title'
               style={Theme.of(context).primaryTextTheme.title},
             />}
          />

少一点样板,就不用说了,因为在结构上是继承的。

但为什么只针对某些属性? 以及如何处理有两个子插槽的情况,例如 ListItem? XML-ish 语法似乎不能很好地处理这个问题。

另外,我不确定它的样板文件更少。

比较:

   <Container style={style}>
      <Row>
        <IconButton
            icon={<Icon name={Icons.menu}/>}
            tooltip='Navigation menu'
            onPressed={null}
        />
        <Expanded> {title} </Expanded>  
      </Row>
    </Container>
   Container(style: style,
      child: Row(
        children: [
          IconButton(
            icon: Icon(Icons.menu),
            tooltip: 'Navigation menu',
            onPressed: null,
          ),
          Expanded(child: title),
        ],
      ),
    )

我完全不清楚 XML-ish 语法是否更简洁或更少样板。 有更多的标点符号和一些重复的内容(例如在关闭标签中)。 而且你必须添加一些名字,所以当然,你失去了“孩子”,但你在图标上获得了“名字”。

同样使用 XML,您如何明确 Row 可以接受零个、一个或多个孩子,而 Center 必须只有一个孩子? 如果有人这样做会发生什么?:

   <Center> <Test/> <Test/> </Center>

它与 (2) 相关,因为它使工具制造者,特别是 GUI 构建者的生活变得更加容易,因为他们不需要完全解析 Dart;

但是,如果我们也有 Dart 解析 API,他们就不需要完全解析 Dart,对吧? 我的意思是,您将解析您想要解析的内容并留下其余部分。 另外我不确定它实际上是否更容易解析,因为它实际上不是 XML; 见下文。

但它也使阅读代码更容易。

我完全不相信这里的 XMLy 版本更容易阅读。 一旦你阅读了一些构建函数,你很快就会习惯嵌套的构造函数语法。

XML 的格式非常简单,所以当您看到“{}”时,您就知道它正在计算 dart 中的表达式。

不过,它实际上不是 XML,对吧? 它是 XML 的一些变体。 是否有明确定义的解析规则? 例如,这是有效的吗?

  <Test name={describe("}")}>

不解析 Dart 怎么知道第一个“}”不是属性表达式的结尾?

反之亦然,当阅读飞镖代码时,你会看到 ') 您知道对象层次结构是从 XML 标记创建的。

您今天看到new关键字时也知道这一点,对吧? 或者当您看到任何大写单词时,确实在上面的无新标记建议中。 这真的是 XML 的好处,还是您对 XML 比对 Dart 更熟悉?

同样在最终的 XML 处理器中,我会避​​免将对象传递给父母的属性,而是创建子标签,如下所示:

我真的不明白你在这里提出什么建议。 据我所知,它根本不是格式良好的 XML。 您能否详细说明您提出的语法是什么以及它是如何工作的? 例如,“Text”构造函数似乎消失了; 处理器怎么知道的

创建一个文本小部件? <pi="37">对不起,如果我听起来是防御性的或攻击性的。 :-) 这是一个多次出现的话题,但我之前从来没有人愿意真正争论这个案子,所以我发现这个对话对于教我请求背后的推理非常有用。请不要把我争论的语气当作不屑一顾,我对你在这里的意见很感兴趣。</p>

看,你把我说的一切都混在一起了,这次谈话毫无进展。 从法律上讲,您是“对证人进行獾”。

如果您真的有兴趣了解 JSX 为何如此火爆,只需在 Google 上搜索“react tutorial”,并注意过去 2 年所有关于 React 的文章都使用 JSX。 在 React 中创建组件层次结构的原始方式(相当于 Flutter 中的当前方式)再也没有被提及,因为 JSX 成为了首选方法(最佳实践)。

https://facebook.github.io/react/tutorial/tutorial.html
https://facebook.github.io/react-native/docs/flatlist.html

另一个有趣的事情是 Typescript 也采用了 JSX:
https://www.typescriptlang.org/docs/handbook/jsx.html

您未能理解 XML 解析(使用一些额外的代码来正确跳过“{}”)比完全解析像 Dart 这样的编程语言要简单几个数量级。 这是事实。 您假设工具构建者将在他们的开发中使用 Dart,而不是实际情况,Intellij 很可能在他们支持 Dart 的 IDE 上使用 Kotlin 和 Java(它们是一种特殊情况,因为它们专注于语言解析;其他人都将难以完全从另一种语言解析 Dart)。

我喜欢将 XML 放入另一种语言的原因在于它提供了两者之间的认知分离,因为 XML 与编程语言非常不同。 只需滚动浏览源文件,您就可以轻松查看什么是代码以及什么是声明性标记。 使用伪装成标记的 dart 代码无法做到这一点。

停止挑剔未完全指定的事物。 你所有的疑问都已经得到解答,只需了解更多关于 JSX 是如何处理的。 我只是没有时间在这里。

如果我听起来很防御或咄咄逼人,我很抱歉。 这是一个多次出现的话题,但我之前从来没有人愿意为这个案子辩护,所以我发现这个对话非常有用,可以教我请求背后的原因是什么。 请不要把我争论的语气当作不屑一顾,我对你在这里的意见很感兴趣。

请不要觉得你必须回复。 我在这里发表评论是为了让我们能够以一种或另一种方式做出决定或设计之前必须解决的问题保持透明。 这基本上只是一个苏格拉底式的对话。 欢迎您的参与,但您当然不应该认为捍卫您的提案是您的责任。


我毫不怀疑 JSX 很“热”。 在 React 中,非 JSX 语法比本期中提出的替代语法(看起来像我们当前的代码但没有“new”和“const”关键字的语法)差很多。 我想了解的是,JSX 在 React 中“热”的原因是否同样适用于 Flutter。

关于 TypeScript 做 JSX,2012 年我参与了指定E4H的工作,甚至在此之前还有E4X 。 两种努力都失败了。 所以对我来说重要的是,我们了解人们究竟喜欢 JSX 和其他语法。

解析 XML 并不容易,解析某种 XML 但带有花括号的东西也并不容易。 解析某种 XML 但带有花括号的东西——不知何故嵌入在另一种语言中更不容易。 但是,实现起来有多容易可能并不是什么大问题,因为它会被实现一次或两次,然后执行它的库将被重用。 (我已经大量参与编写解析 HTML 的规范并参与了类似的 XML 工作,并且我已经为 Dart 实现了解析器,所以我非常清楚解析标记语言与编程语言的难度实际上是。)

我喜欢将 XML 放入另一种语言的原因在于它提供了两者之间的认知分离,因为 XML 与编程语言非常不同。 只需滚动浏览源文件,您就可以轻松查看什么是代码以及什么是声明性标记。 使用伪装成标记的 dart 代码无法做到这一点。

但是为什么能够做到这一点是有益的呢?

滚动浏览构建函数所在的 Flutter 应用程序时,这一点非常明显(它们是巨大的嵌套表达式)。 与“代码”分开很重要的“声明性标记”是什么?

停止挑剔未完全指定的事物。 你所有的疑问都已经得到解答,只需了解更多关于 JSX 是如何处理的。 我只是没有时间在这里。

据我所知,JSX 没有处理我所询问的事情。 例如,React 没有子槽的概念。 我能找到的最接近的事情是他们通过切换回 JS 然后在里面切换回 JSX 来做的事情,所以你需要能够解析编程语言和标记语言。

我想了解的是,JSX 在 React 中“热”的原因是否同样适用于 Flutter。

是的,同样的事情也适用于这里。 当前的方式对您来说看起来不错,因为这是您唯一的选择。 给人们第二个选择,同样的事情也会发生。

E4X 是否消亡无关紧要,因为没有什么是永恒的。 我经常将 ActionScript 与 E4X 一起使用,并认为 Adob​​e 在这方面做得非常出色。 在某种程度上,Flutter 只是带有 Flex 应用程序的 Adob​​e Flash 的更新版本。

(我已经大量参与编写解析 HTML 的规范并参与了类似的 XML 工作,并且我已经为 Dart 实现了解析器,所以我非常清楚解析标记语言与编程语言的难度实际上是。)

太好了,因此您知道与解析命令式编程语言相比,解析标记语言是微不足道的。

但是为什么能够做到这一点是有益的呢?

代码可读性和简单性反过来又带来了一大堆其他好处。

滚动浏览构建函数所在的 Flutter 应用程序时,这一点非常明显(它们是巨大的嵌套表达式)。 与“代码”分开很重要的“声明性标记”是什么?

在你巨大的嵌套表达式上,你能很容易地看到结构吗? 这种结构可以被其他工具(如 GUI 构建器)轻松操作吗? 我的意思是,就像 Adob​​e Flex Builder 使用的那样,拖放小部件,将它们连接到 UI 上,然后切换到代码视图并编辑您想要的任何内容,然后切换回 gui 模式并继续操作小部件。 当程序员进入您的“巨型嵌套表达式”并编写任何不遵循 GUI 编辑器期望的结构的有效 dart 代码时,您不能轻易做到这一点。 使用固定的 XML 结构,这不是问题。

据我所知,JSX 没有处理我所询问的事情。 例如,React 没有子槽的概念

它处理得很好,你只是不知道该怎么做。 因此,接下来只需将有问题的示例放在这里,我将为您提供我认为的 JSX 版本应该是什么。

  new ListTile(
    title: new Text('CineArts at the Empire',
        style: new TextStyle(fontWeight: FontWeight.w500, fontSize: 20.0)),
    subtitle: new Text('85 W Portal Ave'),
    leading: new Icon(
      Icons.theaters,
      color: Colors.blue[500],
    ),
  ),
  <ListTile>
    <title> 
      <Text style={{fontWeight: FontWeight.w500, fontSize: 20.0}}>
         CineArts at the Empire
      </Text>
    </title>
    <subtitle>
      <Text>85 W Portal Ave</Text>
    </subtitle>
    <leading>
      <Icon data={Icons.theaters} color={Colors.blue[500]}/>
    </leading>
  </ListTile>,

它看起来比飞镖版本长,但我可以将所有内容放在相同数量的行中。 事情是 IDE/Editor 可以提供“+”和“-”来展开和折叠这些 XML 节点。

让 React 开发人员看起来熟悉 Flutter,你就有机会吸引一大群新用户使用 Flutter。

E4X 是否消亡无关紧要,因为没有什么是永恒的。

它是否死了不是问题,而是它为什么死了。 它是否因为没有提供人们想要的解决方案而死亡? 它是否因为实施问题而死亡? 是不是因为专利问题死了? 是不是太早了? 太晚了? 我认为从过去的经验中吸取教训很重要。 为什么 E4X 和 E4H 在 JSX 成功的地方却失败了?

我发现有趣的是,刚接触 Flutter 的人通常会要求两件事:标记语言和动画 GIF。 三个月后,他们仍然要求动画 GIF,但不是标记语言。 这可能是因为一旦你习惯了在 Dart 中编写构建方法,实际上就不需要标记语言了。 可能是他们仍然想要一种标记语言,但已经解决了这个遗漏,所以不想再问了。 值得弄清楚是哪一个,否则我们会冒着将精力花在错误选择上的风险(无论朝哪个方向)。

在你巨大的嵌套表达式上,你能很容易地看到结构吗?

是的,至少和使用 XML 一样容易。 就个人而言,我发现 XML 非常冗长,而且它混淆了结构。 但我认为这更多的是关于你习惯的。

(我们还在试验 IDE,它们会为您添加虚拟“结束标签”注释,这样您就可以看到结构而无需实际编写它。)

太好了,因此您知道与解析命令式编程语言相比,解析标记语言是微不足道的。

我的经验是,在确定一种语言的解析难易程度时,声明式与命令式并不是重要的区别。 (例如,HTML 是“声明性的”,但它可能是我处理过的最复杂的解析语言之一。)

代码可读性和简单性反过来又带来了一大堆其他好处。

如果这是主要好处,那么这是我们可以测试的。 我们可以将习惯于编写 HTML、React、iOS 代码、Android 代码、Flutter、命令行应用程序等的工程师混合在一起,向他们展示各种语法,并让他们描述他们认为生成的 UI 看起来像。 然后,我们可以衡量哪种语法得到最好的结果。 @InMatrix这是我们可以在动画工作结束后看看的东西,也许?

这种结构可以被其他工具(如 GUI 构建器)轻松操作吗?

是的,至少在原则上是这样。 将 Dart 表达式机械地转换为 XML 或 JSON 或任何其他可能使用的结构化语言应该是相对简单的。 这只是转换语法的问题,实际信息是相同的。 就我个人而言,如果我正在制作 GUI 编辑器,我不会将其转换为不同的语法,我会直接从 Dart 将其解析为内存中的数据结构。

当程序员进入您的“巨型嵌套表达式”并编写任何不遵循 GUI 编辑器期望的结构的有效 dart 代码时,您不能轻易做到这一点。 使用固定的 XML 结构,这不是问题。

问题是,您可以在 XML 结构中放入与在 Dart 表达式中完全相同的“任何有效的 dart 代码”。 它们在机械上是可以互换的。 所以我真的不明白使用 XML 有什么特别的帮助。 例如,您将如何将其转换为 XML?:

new ListView.builder(
  padding: new EdgeInsets.all(8.0),
  itemExtent: 20.0,
  itemBuilder: (BuildContext context, int index) {
    return new Text('entry $index');
  },
)

它处理得很好,你只是不知道该怎么做。

我的意思是 JSX。 我同意您提出的语法将是解决问题的一种完全有效的方法。

我在 Adob​​e 的 Flex SDK 上工作,它结合了 XML 标记和 ActionScript,在 Adob​​e 存在该产品的最后几年。 我理解标记对定义 UI 的吸引力,但我也记得一些缺点:

  • Flex 应用程序的视觉效果可以根据标记和代码来定义。 我记得,代码往往在大型现实世界应用程序中占主导地位。 对于定义为标记和代码的复杂混合体的应用程序来说,可读性不一定有好处。
  • “Flex Builder”IDE 必须支持由标记和代码定义的应用程序。 这使得 IDE 难以构建和维护。 开发人员倾向于将其视为一种 ActionScript 工具。
  • 发展和维护 XML“编译器”是一个巨大的负担,让工程师团队全职忙碌。 使编译器和工具包保持同步会减慢整个 sdk 的发展。

已经好几年了,我已经记不起所有的细节了。 然而,我的总体印象是,使用标记和代码的组合定义 UI 充其量是一个混合包。

它是否死了不是问题,而是它为什么死了。 它是否因为没有提供人们想要的解决方案而死亡? 它是否因为实施问题而死亡? 是不是因为专利问题死了? 是不是太早了? 太晚了? 我认为从过去的经验中吸取教训很重要。 为什么 E4X 和 E4H 在 JSX 成功的地方却失败了?

它死了,因为 E4X 仅在仅在 Adob​​e Flash/Flex 内部使用的 ActionScript 中实现,而 Adob​​e 终止了该项目。 相反,Adobe 将方向转向开放标准,在这种标准中,没有单一来源的供应商可能会锁定和生态系统内爆。

我发现有趣的是,刚接触 Flutter 的人通常会要求两件事:标记语言和动画 GIF。 三个月后,他们仍然要求动画 GIF,但不是标记语言。 这可能是因为一旦你习惯了在 Dart 中编写构建方法,实际上就不需要标记语言了。 可能是他们仍然想要一种标记语言,但已经解决了这个遗漏,所以不想再问了。 值得弄清楚是哪一个,否则我们会冒着将精力花在错误选择上的风险(无论朝哪个方向)。

好吧,如果我问你 2 件事,而你在 3 个月内没有做任何一件事情,并且有第一件事的替代方案,我也只会问你考虑到你的响应能力和之前的交付表现,完全不可能做的事情。

(我们还在试验 IDE,它们会为您添加虚拟“结束标签”注释,这样您就可以看到结构而无需实际编写它。)

有点好笑,但这就像您之前提到的 XML 结束标记太冗长了。

如果这是主要好处,那么这是我们可以测试的。 我们可以将习惯于编写 HTML、React、iOS 代码、Android 代码、Flutter、命令行应用程序等的工程师混合在一起,向他们展示各种语法,并让他们描述他们认为生成的 UI 看起来像。 然后,我们可以衡量哪种语法得到最好的结果。 @InMatrix这是我们可以在动画工作结束后看看的东西,也许?

当然你可以继续这样做,我相信你会发现“一旦你做了 React(使用 JSX),你就再也回不去了”。 调查有经验的 React 开发人员并询问他们是否认为 JSX 很糟糕并且不应该这样做。 展示你的方式并询问他们是否想用你拥有的东西替换 JSX。 在你这样做之前,关上门并锁上这个地方,因为这些开发人员只是要抓起他们的东西并冲刺到最近的出口。

问题是,您可以在 XML 结构中放入与在 Dart 表达式中完全相同的“任何有效的 dart 代码”。

当然可以,但是对于 GUI 构建器来说,这只是一个不需要触及并且可以轻松跳过的字节块。 使其设计/代码可互换性实际上成为可能,而不是原则上。

new ListView.builder(
  padding: new EdgeInsets.all(8.0),
  itemExtent: 20.0,
  itemBuilder: (BuildContext context, int index) {
    return new Text('entry $index');
  },
)
let style = {
  padding: new EdgeInsets.all(8.0),
  itemExtent: 20.0
};

<ListView.builder style={style}>
  {(context, index) => <Text> entry {index} </Text>}
</ListView.builder>

我以可扩展的方式使用 Adob​​e Flex Builder...

开发人员倾向于将其视为一种 ActionScript 工具。

是的,但我经常从设计视图切换到代码视图,反之亦然。
开始一个屏幕我会去设计视图并使用拖放来布局小部件并生成第一个静态屏幕。 然后我会添加代码和一些静态数据来填充屏幕,这样我就可以向人们展示一些正在运行的东西,看起来像是生产就绪的东西。 生产力令人难以置信。 随着开发的进行,我将前端连接到后端,ActionScript 代码的数量增加了,是的,它主导了整个代码,但即使在接近发布时间的时候,我也经常使用设计视图来调整 UI,而无需深入研究代码。

然而,我的总体印象是,使用标记和代码的组合定义 UI 充其量是一个混合包。

不是在当今世界。 命令式语言在 Python 哲学中得到了发展,非常适合开发。 随着 React 的出现,带有嵌入式标记 (XML) 的声明性技术成为主流; JSON 成为首选的基于文本的数据格式。

E4X 仅在 ActionScript 中实现

E4X 是 ECMA 标准。 Mozilla 发布了一段时间,但随后将其删除(对于浏览器供应商来说,这是一个非常不寻常的举动)。 其他浏览器供应商从不想实现它。 (不过,他们已经实现了其他新的 ECMA 功能。)对于 E4H,浏览器供应商从来没有对实现它感兴趣(尽管他们已经实现了我帮助发明的许多其他东西)。

好吧,如果我问你 2 件事,而你在 3 个月内没有做任何一件事情,并且有第一件事的替代方案,我也只会问你考虑到你的响应能力和之前的交付表现,完全不可能做的事情。

这是一种可能的理论。 不过,人们倾向于要求除此之外的许多其他东西,而且他们要求的许多东西都得到了实现,而且动画 GIF 也有解决方法,所以我不确定这是否能完全解释这种情况。

有点好笑,但这就像您之前提到的 XML 结束标记过于冗长。

的确。 这是一项可选的 IDE 功能,您不必将其写入代码中,但这对于冗长是否是一个问题有很大的不同。

... ListView ...

GUI 编辑器将如何处理此标记? 我真的不明白如何为此可视化 UI。

这可能是对此请求的反驳,和/或如果您想要标记,请记住一些见解。 我有强烈的感觉,添加标记会给 GWT 带来一些挑战,我不想看到另一个 API 通过。

我已经看到其他几个框架在 UI 构建方面经历了这种转变。 像这样的标记非常适合工具,到目前为止,它对 IDE 开发人员来说是天堂般的。 更容易区分谁做什么的责任。 虽然我认为它可以做得更好。

GWT 以这种方式开始,使用 Java 构建 UI。 然后出现了 UiBinder,您可以在其中使用规范构建 xml 标记的 UI。 然后,Eclipse Plugin 工具能够在 xml 标记中生成 UI。 Android 也在这样做,无需赘述。 所以我所看到的情况是,标记对 UI IDE 开发人员来说非常有用。 但实际上,标记是一项巨大的时间投资,并增加了复杂性工具以将其转换为实际程序。 工具总是最后来的。 因此,与此同时,当所有这一切都在现实中显现时,有两个世界。 做任何事情的两种有趣的方式。 一种是默认语言,一种是标记。 所以我今天支持 GWT。 当我编写文档时,我必须编写两次,一次用于 Java,一次用于 UiBinder XML Markup。 所以真正的问题是,如果你想走标记之路,我认为应该问这个问题,增加的复杂性是否值得一游!

我认为 JSX 旨在解决您希望将 HTML 和 javascript 的操作融合在一起的其他问题。 确实感觉标记规范增加的复杂性不适合使用标记编写 UI 的需要。 尤其是当您没有真正将文档标记语言作为目标时。 至少不适合日常用户。

积极的一面。 我喜欢从事工具工作。 所以我可以看到标记语言非常有用。 使用标记时编写和修改 AST 要容易得多。

但是话又说回来,如果你在工作上有足够的头脑,那么你做什么并不重要。 归根结底,如果开发人员可以使用您的 api 更快地编写他的应用程序,那么您将获得牵引力。 但是工程团队的成本是多少。

我认为真正的问题是,如何更快地构建 UI。 我认为工具可以编写飞镖,跳过任何中间人标记。 而且我的目的并不是真的说它不值得,而是如果走这条路,真的要计算所有方面的成本!

E4X 是 ECMA 标准。 Mozilla 发布了一段时间,但随后将其删除(对于浏览器供应商来说,这是一个非常不寻常的举动)。 其他浏览器供应商从不想实现它。

我想说只有 Adob​​e 完全支持 E4X 并且在开发人员中拥有良好的追随者。 浏览器供应商确实一直在他们的浏览器中添加和删除内容。 Google 没有删除 MathML 支持吗?

这是一种可能的理论。 不过,人们倾向于要求除此之外的许多其他东西,而且他们要求的许多东西都得到了实现,而且动画 GIF 也有解决方法,所以我不确定这是否能完全解释这种情况。

这是关于 React 和 JSX 的事情。 你真的不会完全理解 React 带来的东西,直到你用它开发一段时间,然后它变成了晚上和天反对所有其他框架。

GUI 编辑器将如何处理此标记? 我真的不明白如何为此可视化 UI。

let style = {
  padding: new EdgeInsets.all(8.0),
  itemExtent: 20.0
};

<ListView.builder style={style}>
  {(context, index) => <Text> entry {index} </Text>}
</ListView.builder>

我会代表\作为一个矩形,如果它的子/子在其他小部件中,我会在其中放置矩形。
由于在这种情况下孩子是一个函数,您可以简单地放置一个矩形,上面写着“不可编辑/代码”来告诉用户这个小部件是由代码创建的,或者在这种情况下很容易推断出该函数是对小部件并简单地呈现它; 我的意思是一个矩形,它表示该函数是一个浅层函数包装器,并且在它内部是列表项小部件矩形(\在这种情况下)。

但实际上,标记是一项巨大的时间投资,并增加了复杂性工具以将其转换为实际程序。

我所要求的只是在 Dart 编译器上添加这些简单的扩展,以便如果开发人员愿意,他们可以使用这种 XML 结构进行编写。 旧的方法将继续有效,并且这样做所涉及的工作量并不大。 您实际上可以看到 babel.js 编译器执行 JSX 需要多少行代码,我说的是数百行而不是数千行(我刚刚检查过)。

工具总是最后来的。 所以与此同时,虽然所有这些都体现在现实中,但有两个世界。 做任何事情的两种有趣的方式。 一种是默认语言,一种是标记

当然,但 React 一直是这样,这根本不是问题。

当我编写文档时,我必须编写两次,一次用于 Java,一次用于 UiBinder XML Markup。

不在 React 中,因为标记存在于代码中。

增加的复杂性值得一游!

当然,这就像你是否应该用最新技术培训你的开发人员并冒着他们离开你公司的风险的争论。 更大的风险是让他们未经训练。 因此,您必须采用最新的技术,否则就有被抛在后面的风险。

React 以最新的技术引领着开发 UI/UX 的旅程。 它对开发人员具有巨大的吸引力。 你最大的风险是没有达到 React 标准。

我认为 JSX 旨在解决您希望将 HTML 和 javascript 的操作融合在一起的其他问题

JSX 不仅适用于 HTML,React Native 从 XML 标记生成视图(如 Flutter Widgets)。

我认为真正的问题是,如何更快地构建 UI。

更像是如何更好地构建 UI/UX。 更好的含义:更快、更高质量(代码和 UI/UX)、流畅的设计师-开发者交互等。

顺便说一句,开发人员工具做得非常好; “颤振医生”太棒了!!!
我现在正在用煤气做饭,而且很有创意;)

我只是想回答这里提出的可读性问题,尽管我理解可读性只是我们需要考虑的众多因素之一。

代码可读性和简单性反过来又带来了一大堆其他好处。

如果这是主要好处,那么这是我们可以测试的。 我们可以将习惯于编写 HTML、React、iOS 代码、Android 代码、Flutter、命令行应用程序等的工程师混合在一起,向他们展示各种语法,并让他们描述他们认为生成的 UI 看起来像。 然后,我们可以衡量哪种语法得到最好的结果。 @InMatrix这是我们可以在动画工作结束后看看的东西,也许?

当然有一些方法可以凭经验研究代码的可读性,到了 Q4 计划的时候,我们可以进行更严肃的讨论。 为了使这样的研究有用,我们需要在 Flutter 编程的上下文中定义什么样的阅读任务对开发人员来说是重要的。 除了阅读整个构建方法并描绘生成的 UI 可能是什么之外,可读性还影响较小的任务,例如识别 dart 文件中的构建方法、匹配大括号、读取内联注释等。

为了支持一些范围更窄的任务,我们可以先在编辑器中试验 UI 增强功能,这通常比引入和维护标记语言便宜。 VS 代码中的结束标签功能就是这样的 UI 增强功能之一,我们应该了解它如何很好地解决了它要解决的大括号匹配问题。 在这个领域还有很多其他的选择我们还没有尝试过。 例如,可以使用不同的字体或背景颜色来显示构建方法,以帮助开发人员在心理上将其与其他代码区分开来。

让我印象深刻的另一件事是我们如何鼓励人们不要编写庞大的构建方法并利用框架的组合特性。 如果构建方法高于屏幕高度,那么无论是 Dart 还是 XML,都将难以阅读。

让我印象深刻的另一件事是我们如何鼓励人们不要编写庞大的构建方法并利用框架的组合特性。 如果构建方法高于屏幕高度,那么无论是 Dart 还是 XML,都将难以阅读。

这不仅仅是构建方法。 这是构建方法调用来构建小部件树的所有其他方法。 在 React 中很常见的是使用较小的方法来构建子树片段,然后将它们调用到更大的树中。

同样在带有 JSX 的 WebStorm 中,每个 XML 节点都有 +/-,可用于展开/折叠节点和子节点,以使大于屏幕高度的阅读结构更容易。

我们在 Flutter 中发现的一件事是大型构建方法对性能没有好处,我们试图鼓励人们将他们的构建方法分解为更小的可重用小部件。 特别是,在 Flutter 中,有一个基于其他方法的结果构建的构建方法在某种程度上是一种反模式,我们宁愿阻止它,也不愿让它变得更容易。 (这在某种程度上是最近才意识到的,所以我们的很多示例和小部件还不能很好地做到这一点。)

我们试图鼓励人们将他们的构建方法分解为更小的可重用小部件。

它真的成为一个可重用的小部件还是只是一个包装器/复合小部件? 我的意思是可重用你应该至少有 2 个使用实例。

https://flutter.io/catalog/samples/basic-app-bar/上的 AppBar 是如此独特,以至于您不能真正将其称为可重用组件; 它是一个包装器/复合组件,在这些情况下,为什么不直接使用本地方法来构建 UI 的那部分呢? 我想如果它做了更多的事情,将它放在包装器/复合组件中是有意义的。

我们在 Flutter 中发现的一件事是大型构建方法不利于性能

既然你提到了性能,让动画循环驱动构建方法会导致平滑动画的性能问题。 您不希望您的 build 方法每秒调用 60 次或更多,特别是考虑到 build 方法是用户代码(例如,它可能有一个超长的循环,并且会导致动画跳过)。 作为一个 Flutter 初学者,也许我弄错了。

https://flutter.io/catalog/samples/basic-app-bar/上的 AppBar 非常独特,以至于您不能真正将其称为可重用组件

它也相对较小,所以没关系。

关于性能,这对于这个问题来说有点离题,所以如果你想讨论它,请提交一个新问题(或发送电子邮件至 flutter-dev 或在堆栈溢出上发帖,无论你喜欢什么)。

看到这个问题被埋没真是太疯狂了。 在我看来,对于 Flutter 来说,实现类似于 JSX 的语法来组合小部件将是成败的关键。

我根本不了解目标受众,许多 ios 和 android 开发者正在转向 react native,这似乎是收获市场份额的绝佳机会。

我鼓励参与的人给 react native 一个旋转,看看我们在说什么。

我一点也不怀念 Flutter 中的 JSX。 这只会使框架和工具膨胀,从而在这里和那里获得一些小的收益。

@birkir在这个问题上我 100% 支持你。 缺少与 Flutter 完美契合的 JSX,让 Flutter 显得陈旧生锈,感觉像是 1990 年代的技术。 实际上,似乎每个人都在以某种方式采用 JSX。 最新的一个是流行的 Vue.js 框架。

+1

@zoechi你以前使用 JSX 的经验是什么,你是真的用过它还是只是看过它? 我认为你们低估了 JSX,说它会在这里和那里带来很小的收益。 如果你没有任何用户,你就没有产品。

@birkir我在这里看到了很多关于 JSX 的兴奋,但似乎没有人费心解释 Flutter 从拥有这样的 DSL 中究竟会获得什么,除了可能具有更好的可读性,这主要是主观的。

更多功能通常只会占用框架而不是改进它。
实施它们还消耗了其他领域缺少的大量资源,而缺少的功能实际上会阻止人们实施某些应用程序。

因此,如果您对 Flutter 获得 JSX 之类的东西感到兴奋,那么您应该投入时间和精力来撰写令人信服的论据。
仅仅因为其他人也有而添加一些东西,这可能是最弱的论点。

还有计划改进 Dart 以减少编写 Flutter UI 代码的冗长,这进一步削弱了 JSX 的案例。

那么你有哪些令人信服的论据呢?

真的 !!! “似乎没有人费心解释 Flutter 究竟会获得什么……等等等等”。
你没有完整阅读这个主题吗? 你的注意力是否超过了你对 JSX 的了解?

你们患有 NIH 综合症(此处未发明)。 “好艺人抄,大艺人偷窃”,平庸的艺人,好吧,表现得像你。

只是支持 JSX 相对简单,它将极大地帮助吸引新客户(React Native 移动开发人员)加入该平台,这使它成为你们看不到的明智之举。 对于平台来说,它并不大胆。

请大家在辩论时保持建设性的语气。

因为其他人拥有它而添加功能是弱论点。 好的。
为什么flutter会有热重载? 那个是从哪里来的? 耶稣伙计。

我们如何未能为你们提供可靠的论据? 项目牵引力和吸引开发人员是我们的首要原因。

原因二,可读性

https://github.com/flutter/flutter/blob/master/examples/flutter_gallery/lib/demo/cupertino/cupertino_buttons_demo.dart vs https://gist.github.com/birkir/e921158239c324ab95bb0b174383a562

原因三, GUI Builders 。 我将引用自述文件中的第一行。

一个新的移动应用程序 SDK,可帮助开发人员和设计人员构建适用于 iOS 和 Android 的现代移动应用程序。

我不希望看到 Flutter 在达到 beta 之前就和 Polymer 一样陷入困境。

项目牵引力和吸引开发商

关系仍不清楚。

原因二,可读性:

让 Dart 代码更具可读性对我来说似乎是一个更好的目标

原因三,GUI Builders。 我将引用自述文件中的第一行。

据我记得,上面已经提到,使用 Dart 代码没有理由阻止这种情况。

你的反驳论点并不能真正驳回这个想法,不是吗?

  1. 关系很清楚。 除非项目受欢迎不是目标?
  2. 伟大的! 它会接近 JSX 的可读性吗? 目前对这种事情的提议是什么?
  3. 据说可以做到。 为当前可用的 GUI 构建器调整 JSX 支持会简单得多。

还有计划改进 Dart 以减少编写 Flutter UI 代码的冗长

很高兴看到承认当前的方式可以使用一些改进。
请务必提供有关此类提案的详细信息。 最好的办法是与 React Native 社区互动以获取反馈。

几个 Dart 语言功能请求可以使代码更短/更易读:

通过这些更改,代码可能如下所示:

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Cupertino Buttons')),
      body: Column(
        Padding(padding: EdgeInsets.all(16.0),
          Text(
            'iOS themed buttons are flat. They can have borders or backgrounds but '
            'only when necessary.'
          ),
        ),
        Expanded(
          Column(mainAxisAlignment: MainAxisAlignment.center,
            Text(_pressedCount > 0
                   ? 'Button pressed $_pressedCount time${_pressedCount == 1 ? "" : "s"}'
                   : ' '),
            Padding(padding: EdgeInsets.all(12.0)),
            Align(alignment: Alignment(0.0, -0.2),
              Row(mainAxisSize: MainAxisSize.min,
                CupertinoButton(onPressed: () { setState(() { _pressedCount += 1; }); },
                  Text('Cupertino Button'),
                ),
                CupertinoButton(onPressed: null,
                  Text('Disabled'),
                ),
              ),
            ),
            Padding(padding: EdgeInsets.all(12.0)),
            CupertinoButton(
              color: CupertinoColors.activeBlue,
              onPressed: () { setState(() { _pressedCount += 1; }); },
              Text('With Background'),
            ),
            Padding(padding: EdgeInsets.all(12.0)),
            CupertinoButton(
              color: CupertinoColors.activeBlue,
              onPressed: null,
              Text('Disabled'),
            )
          ),
        ),
      )
    );
  }

此外,根据您的 IDE,您可以选择在括号末尾添加合成注释,您可以在 IDE 中看到类似这样的内容:

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Cupertino Buttons')),
      body: Column(
        Padding(padding: EdgeInsets.all(16.0),
          Text(
            'iOS themed buttons are flat. They can have borders or backgrounds but '
            'only when necessary.'
          ),
        ),
        Expanded(
          Column(mainAxisAlignment: MainAxisAlignment.center,
            Text(_pressedCount > 0
                   ? 'Button pressed $_pressedCount time${_pressedCount == 1 ? "" : "s"}'
                   : ' '), // Text
            Padding(padding: EdgeInsets.all(12.0)),
            Align(alignment: Alignment(0.0, -0.2),
              Row(mainAxisSize: MainAxisSize.min,
                CupertinoButton(onPressed: () { setState(() { _pressedCount += 1; }); },
                  Text('Cupertino Button'),
                ), // CupertinoButton
                CupertinoButton(onPressed: null,
                  Text('Disabled'),
                ), // CupertinoButton
              ), // Row
            ), // Align
            Padding(padding: EdgeInsets.all(12.0)),
            CupertinoButton(
              color: CupertinoColors.activeBlue,
              onPressed: () { setState(() { _pressedCount += 1; }); },
              Text('With Background'),
            ), // CupertinoButton
            Padding(padding: EdgeInsets.all(12.0)),
            CupertinoButton(
              color: CupertinoColors.activeBlue,
              onPressed: null,
              Text('Disabled'),
            ), // CupertinoButton
          ), // Column
        ), // Expanded
      ), // Column
    ); // Scafold
  }

这场对话越来越激烈。 我想鼓励大家阅读我们的行为准则:
https://flutter.io/design-principles/#conflict -resolution
几天后,我将结束这次谈话,每个人都在考虑如何以尊重和富有成效的方式做出贡献。

我们都知道,构建 UI 的语法是移动开发体验中非常重要的一部分。 现在语法有点冗长,我必须new一些东西只是为了添加边距: margin: new EdgeInsets.symmetric(horizontal: 4.0) ,我认为可能有更简单的方法。

是否有可能像 Kotlin 团队为 Android 开发人员所做的那样构建 DSL? 它被称为Anko ,一种用于构建 Android UI 的 DSL:

verticalLayout {
  padding = dip(30)
  editText {
    hint = "Name"
    textSize = 24f
  }
  button("Login") {
    textSize = 26f
  }
}

简洁的语法有助于保持代码的可读性和可维护性,还可以使构建工作愉快,这很重要。 请 Flutter 团队认真评估后再做决定。 我们都希望看到 Flutter 在未来几年取得更大的成功。

请不要向 Flutter 引入类似 XML 的语法。

我用 Android Java 编程了一年多,然后我开始寻找一个跨平台的工具集来尝试。
我从 React Native 开始,然后尝试了 React。 我不太喜欢 JSX 语法,因为它既不是 javascript 也不是 html,所以只是要学习的另一件事。
当我尝试 Flutter 时,我发现它更容易上手(可能主要是由于我的 Java 背景)。

我认为我不希望看到将 XML 语法添加到 flutter 的一些原因:

  1. 另一件要学习的事情 - 可以用来学习 Futures ;P
  2. 上下文切换 - 您在 XML 和代码之间进行上下文切换,这只是不必要的认知负担。
  3. 有几天我早上用 Java 编程,下午用 Python 编程。 使用 React,您可能需要在一个代码库中理解 Javascript、Babel、JSX、HTML、CSS 等。
  4. 在 Flutter 中不需要 XML 的原因是因为 dart 有命名参数,可以很好地替换 XML 属性。
  5. Dart 有非常酷的 dartfmt,它可以毫不费力地缩进代码。

与安卓相比

  1. 无论如何你必须学习编程方式,为什么要添加另一种做事方式?
  2. android 中的 XML 布局在设备上显示更改的速度更快,但在 Flutter 中运行几乎是即时的,因此添加 XML 不会提供这种优势。
  3. Android XML + 编程组合增加了复杂性,例如膨胀 XML 片段和以编程方式注入 XML 树。
  4. 在 Flutter 中即时运行非常快,您不需要 XML 模型来帮助可视化它的外观,您只需按一个键即可立即看到更改。
  5. 程序化布局问题的错误与 XML 中的布局问题不同,因此您需要了解两组内容。

我会更进一步,删除 pubspec.yaml 并将其替换为 pubspec.dart 并在 dart 代码中进行配置。

如果开发人员抱怨在视觉上布置页面的难度 - 一个想法是创建一个布局设计器,让您可以通过拖放来设置主题和设计页面。 然后它将生成不打算编辑的 Flutter 代码,而是创建可用于编写应用程序的类。

它不需要像 Android XML 那样进行双向编辑(XML/布局),但您只需保存布局以备后用。 如果您需要更改它,您可以重新生成代码并(希望)只需更改一些参数。

我知道这个对话很老了,是的,它变得很热,但是我想写几句我认为这里发生的事情。

颤振是新的。 它是一种全新的做事方式。 是的,它确实借鉴了反应范式。 但这并不意味着它需要遵循相同的步骤。 我不认为 Flutter 的团队目标是吸引 React Native 的开发人员加入 Flutter,它只是为了构建开发人员可能会感兴趣的新东西。Google 在与世界分享之前在内部使用它,并且他们一直在生产它。 我与@Hixie分享了它与 JSX 构建 UI 没有任何不同的评论。 是的,它对正确的纯飞镖有点冗长。 但它实际上使调试代码变得更加容易。

我反对标记语言或 JSX 或任何位于技术之上的东西的原因是它需要平台做更多的工作。 您可以很高兴为 UI 编写标记语言,但是您将有这么多在平台上工作的开发人员哭泣并竭尽全力让它为您工作。 另一种观点是 JSX 为 Javascript 社区工作,其主要目标始终是让开发人员更轻松,而不用担心权衡。 不要误会我的意思,用于 web 的 React(JSX) 是天作之合,因为 HTML 无论如何都是标记。 但是对于 React Native 来说,查看存储库中的所有代码,他们必须这样做才能使其工作。 将 JSX 添加到 Flutter 中需要大量工作,并且在添加新功能时需要考虑两件事。 再次只是为了能够删除 child 参数以及 const 和 new 关键字? 我更喜欢知道代码中真正发生了什么并控制正在发生的事情,而不是拥有神奇的语法,它所做的一切都是增加开销。

嗯,这是我的意见。 不想开始新的巨大讨论。 只是提到 JSX 对 react/javascript 社区来说很棒,因为它对他们有用,但对于 Dart/flutter,我发现添加 JSX 只是为了吸引来自 React Native 的开发人员有点矫枉过正。

哇,本来可以写一篇博文的xD

@洛克沃尔

另一件要学习的事情 - 可以用来学习 Futures ;P

要学习的东西使当前的递归对象构造怪物变得更简单,并且对于日常的 React Native 开发人员来说很熟悉,所以我猜人们会更喜欢学习它。

上下文切换 - 您在 XML 和代码之间进行上下文切换,这只是不必要的认知负担。

不是问题,没有上下文切换,它只是使编程 UI/UX 更清洁的环境的一部分。

然后它将生成不打算编辑的 Flutter 代码

为什么不? 那时不是很有用。

@franzsilva

我不认为 Flutter 的团队目标是吸引 React Native 的开发人员来 Flutter

真的 !!! React Native 占据主导地位,鉴于使用跨平台工具的移动开发者总数有限,你真的认为 Flutter 可以在不吸引 React Native 人的情况下成为本垒打吗?

是的,它对正确的纯飞镖有点冗长。 但它实际上使调试代码变得更加容易。

这不是一个正确的说法。 调试 JSX 代码,这只是 javascript 代码并没有更容易或更难,它是一样的。

我反对标记语言或 JSX 或任何位于技术之上的东西的原因是它需要平台做更多的工作。

谁在乎平台上放置了多少工作? 开发人员只想要提高代码可读性和生产力的最新技术。 当更新的东西提供更好的选择时,没有开发人员愿意使用旧的和过时的技术。

我更喜欢知道代码中真正发生了什么并控制正在发生的事情,而不是拥有神奇的语法,它所做的一切都是增加开销。

这是胡说八道,我确切地知道 JSX 发生了什么,它是一个很小的层,几乎可以一对一地转换,但提供了很多好处。 如果你问我,编译时间开销可以忽略不计。

只是提到 JSX 对 react/javascript 社区来说很棒,因为它对他们有用,但对于 Dart/flutter,我发现添加 JSX 只是为了吸引来自 React Native 的开发人员有点矫枉过正。

JSX 也应该适用于 Dart/Flutter。 无论如何,这不是矫枉过正。 为什么 JSX 不适用于 Dart/Flutter 有什么好的理由吗? 如果我要编写代码并发布它,为什么它不适合 Dart/Flutter 开发?

让我们以@xinthink中的具体示例为例:

现在语法有点冗长,我必须new一些东西只是为了添加边距: margin: new EdgeInsets.symmetric(horizontal: 4.0) ,我认为可能有更简单的方法。

如果你想在左边和右边添加一个边距,你想怎么表达? 具体来说,让我们举一个简单的例子,看看它在各种语法中的样子。

  // Flutter as written today
  return new Container(
    margin: new EdgeInsets.symmetric(horizontal: 4.0),
    decoration: new ShapeDecoration(shape: new CircleBorder(), color: Colors.blue[100]),
    child: new AnimatedCrossFade(
      duration: const Duration(seconds: 3),
      firstChild: const FlutterLogo(style: FlutterLogoStyle.horizontal, size: 100.0),
      secondChild: const FlutterLogo(style: FlutterLogoStyle.stacked, size: 100.0),
      crossFadeState: _showHorizontal ? CrossFadeState.showFirst : CrossFadeState.showSecond,
    ),
  );
  // Flutter as written later this year once we remove "new" and "const" keywords
  return Container(
    margin: EdgeInsets.symmetric(horizontal: 4.0),
    decoration: ShapeDecoration(shape: CircleBorder(), color: Colors.blue[100]),
    child: AnimatedCrossFade(
      duration: Duration(seconds: 3),
      firstChild: FlutterLogo(style: FlutterLogoStyle.horizontal, size: 100.0),
      secondChild: FlutterLogo(style: FlutterLogoStyle.stacked, size: 100.0),
      crossFadeState: _showHorizontal ? CrossFadeState.showFirst : CrossFadeState.showSecond,
    ),
  );

你会建议我们如何表达这些_exact_语义?

  // Remove "new" and "const", infer the class for enum values, allow int literals for doubles
  return Container(
    margin: EdgeInsets.symmetric(horizontal: 4),
    decoration: ShapeDecoration(shape: CircleBorder(), color: Colors.blue[100]),
    child: AnimatedCrossFade(
      duration: Duration(seconds: 3),
      firstChild: FlutterLogo(style: horizontal, size: 100),
      secondChild: FlutterLogo(style: stacked, size: 100),
      crossFadeState: _showHorizontal ? showFirst : showSecond,
    ),
  );

Babel.js 有这个简洁的小网站,你可以在其中输入 JSX 并将其转换为纯 Javascript:
https://babeljs.io/repl/# ?babili=false&evaluate=true&lineWrap=false&presets=es2015%2Creact%2Cstage-0&code=function%20hello()%20%7B%0A%20%20return%20%3Cdiv%3EHello% 20world!%3C%2Fdiv%3E%3B%0A%7D

我将为 DSX 到 Dart 做一个等效的。 只是一个概念证明,让我们看看我需要多长时间......

这是@Hixie 在“DSX”中的最新示例,使用 Airbnb 的样式指南并假设所有子元素都可以自动映射到child属性。

return (
  <Container
    margin={EdgeInsets.symmetric(horizontal: 4)}
    decoration={ShapeDecoration(shape: CircleBorder(), color: Colors.blue[100])}
  >
    <AnimatedCrossFade
        duration={Duration(seconds: 3)}
        crossFadeState={_showHorizontal ? showFirst : showSecond}
    >
      <FlutterLogo style={horizontal} size={100} />
      <FlutterLogo style={stacked} size={100} />
    </AnimatedCrossFade>
  </Container>
);

如果目的是提高可读性,我认为未来的 Dart 绝对会胜出。

您必须检查文档以了解什么可以变成标签(大概Widget s),或者需要/允许多少子元素。

如果您的目标是从 JavaScript 输出 HTML,那么 JSX 作为中间地带非常有意义。 因为当您在一天结束时想要标签时, React.createElement('div', null, 'foo')远比<div>foo</div>差。

如果您的目标是从...输出 Dart 对象树,并且格式良好的 Dart 构造函数树是完全(可以说更)可读的,我认为绕行 XML 没有意义。 而且我不会错过那些来自 Android 的 XML。

这就是使用 XML 所实现的... 看起来已经 5 个月了,只是说说而已,现在我正在做一些事情,所以请给我一些时间(我确实有一份全职工作,周末只能抽出大约 4 个小时)。

刚找到这个帖子,两边都很有趣。 作为对 Flutter 感兴趣的 React 开发人员,还有一些我没有提到的其他论点(尽管我只是简要浏览了所有评论。)

  1. 结束标记声明增加了对子项与属性的理解。 不幸的是,UI 可能嵌套得很深,并且有一个清晰的标签与一个未知的标签)有助于澄清和解析孩子。 它还允许我在组件之间移动代码,并且非常声明性地查看它何时不合适(例如,a 之前的结束标记。)这对于多个嵌套的 ) 来说更棘手。

  2. 我对在构造函数中看到多个嵌套组件的最初直觉反应让我回想起“回调地狱” 。 这是 JS 开始变得更好的一个非常痛苦的时代,回到它感觉有点像倒退了一步。

  3. 与#2相关,不幸的事实是我们必须说服人们转换(或至少尝试一下)。 许多人使用 React/React Native,甚至更多人使用 HTML/JS。 创建一个简单且大部分语法熟悉的教程/指南,专门针对 React 的一些痛点,对于那些有点疲倦的人来说可能非常有吸引力。

React 在 Web 开发人员社区中流行的主要原因之一是对 JSX 的支持。

看到这么好的功能请求被“否决”真是令人失望。 它提高了可读性并加快了采用。

我认为这是 Open JavaScript 和 Dart 之间的主要区别。 JavaScript 是真正的开源代码,而对 Dart 的请求会进入这样的对话,最终你会因投反对票而失去动力。

为新想法腾出更多空间!

@jayjun看起来棒极了! 我可以在某个地方试试吗?

@sanketsahusoft不要担心很快你就可以尝试我的版本,它甚至比@jayjun 更好。

快速更新:2 个周末前我的 UI 工作得很好,上周末我让解析器完全工作,一半的转译器工作。 如果我避开超级碗,我希望在即将到来的周末完成它;)

我有厚厚的皮肤和骡子一样的固执,所以我什至没有注意到这些反对票,不过感谢您指出它们。

卡洛斯。

这对丢失结束标签的问题有帮助吗?
想法:自动生成的结束标签

以下是@Hixie示例的一些建议标记语法:

<Container margin=<EdgeInsets.symmetric horizontal=4 />
           decoration=<ShapeDecoration shape=<CircleBorder> color={{ Colors.blue[100] }} />>
    <AnimatedCrossFade duration=<Duration seconds=3 />
                       crossFadeState={{ _showHorizontal ? showFirst : showSecond }}>
      <FlutterLogo style=horizontal size=100 />
      <FlutterLogo style=stacked size=100 />
    </AnimatedCrossFade>
</Container>

@abarth ,您所做的有趣的事情是添加了第三个属性可能性,当它们是另一个标签时,它可以简化表达式的外观。
JSX 有:
1 - <tag attrib=""/><tag attrib=''/>
2 - <tag attrib={}/>
你建议了另一个:
3 - <tag attrib=<anotherTag.../>/>
使用 JSX 你必须把它写成:
<tag attrib={<anotherTag.../>}/>

@cbazza是的,第三种情况在 Flutter 中很常见,因此跳过额外的{嵌套是有意义的。

@abarth啊,但我通过使用类似 css 的样式使大部分这些事情变得不必要! 转译器将这些类似 css 的样式扩展为适当的 Flutter 调用。 现在标签结构更加清晰,样式可以很容易地从 InVision、Figma、Atomic 等设计工具中导入

@cbazza很酷,我使用了许多带有FutureBuilder之类的闭包的小部件。 我希望你的转译器可以生成类似的东西,

return new FutureBuilder(
  future: Firestore.instance
      .collection('stuff')
      .document(id)
      .get(),
  builder: (context, snapshot) {
    if (!snapshot.hasData) {
      switch (snapshot.connectionState) {
        case ConnectionState.waiting:
          return const Text('Loading...');
        default:
          return new Text('${id} not found');
      }
    }

    return new Text(snapshot.data['name']);
  },
);

@jayjun ,是的,这不是问题。 转译器是一个简单的 XML 处理器,在解析表达式({} 中的所有内容)时,它只是变成一个文本块,因此它会逐字逐句写出。

@xinthink

是否有可能像 Kotlin 团队为 Android 开发人员所做的那样构建 DSL?

似乎很多人都想将 Kotlin 与 Flutter 一起使用。 老实说,我不明白,为什么开发人员决定在 Dart 中重新发明轮子?

在我看来,Flutter 不需要 JSX。 Flutter 应该选择 Kotlin 而不是 Dart。 Kotlin 允许我们用开箱即用的优美语法编写复杂的 ui 逻辑,拥有庞大的社区,生产就绪的工具,在 Android 开发中经过实战测试......

只是说。

Kotlin 很好,我是一个粉丝,但它不能在 iOS 上运行......实际上它可以但它还没有发布(现在是预发布阶段)。
对于 UI/UX 开发,我仍然更喜欢 JSX 而不是 Anko DSL。 我喜欢这样一个事实,即我可以在视觉上将声明性标记与命令式代码分开,并且能够很容易地将组件混合和匹配在一起。

Dart、Kotlin 和 Swift 都有相似之处:
https://sethladd.github.io/swift-is-like-kotlin-and-kinda-like-dart/

我喜欢 :

  1. 如果你来自 Java,Dart 会更熟悉。
  2. 您可以利用您的 Dart 技能并使用它们来构建网页 - 这在创建应用程序时很有价值,您可以在 Web 上构建功能(并在 WebView 中显示它们)更有意义(可能是快速管理页面或产品列表)需要谷歌索引)。
  3. Dart 从一开始就是为了编译成 javascript 而构建的,我认为以后添加到语言中并不容易。

这些基本上是我选择 Dart 而不是 Kotlin / Swift / React 的原因。

_虽然在谷歌的新 Fuchsia OS 中支持 Dart 和 Swift 的决定让我感到困惑。_

如果您来自 Java,我不确定 Dart 是否更熟悉。 我来自 Java,对 Kotlin 或 Swift 没有任何问题; 基本上类型声明是颠倒的,没有什么新东西,因为它在 Pascal 和 ActionScript 中使用。

是的,您可以使用 Dart 构建网页,但我认为这方面并没有主流。 唯一在网络上表现良好的其他语言是 TypeScript,因为它与前 3 个最流行的网络框架很好地集成了。

看看 Web 上的 React 可用的不同语法:
https://github.com/Workiva/over_react#fluent -style-component-consumption
两个 Dart 版本都没有机会对抗 JSX !!!

TypeScript 旨在编译为 Javascript,在这方面它比 Dart 更好。 它还支持 JSX。
Dart 正受到四面八方的挤压。 Swift 势头强劲,因此在 Fuchsia OS 上与您的宝宝一起支持它是明智之举。

多久能出原型? 我很想用它!

我使用了一段时间的 React,JSX 将我的工作效率提高了十倍。 这不是一个有争议的问题:其他团队正确地认为这会更好,那么为什么不 Flutter 呢? (修辞:我读了线程......(捂脸))

这个周末我正在努力,但我不断扩大新想法的范围,所以希望这个周末我能有一些东西。

我正在尝试的一些有趣的事情:
1) 在子标签上使用 xml 命名空间,以便在父标签中插入正确的 Dart 命名参数。
2) 扩展运算符以更好地组织类似属性的样式,以便它们可以在地图中的 xml 外部定义/分组,然后像典型的 React 东西一样引入并传播到标签上。
3) styleCSS 属性,从 CSS 生成颤振样式。

(1) & (2) 是通用的,因此适用于所有 Dart Flutter 代码。
(3) 针对 Flutter Widget(容器、文本等)是专门的,我现在只做这 2 个。

@yuriy-manifold 仅仅因为对 JS 有用的东西并不意味着它对 Dart 来说是个好主意。
如果您阅读了上述讨论,您会发现它实际上有争议的。
我不明白为什么两种语言会比一种更好。

仅仅因为对 JS 有用的东西并不意味着它对 Dart 来说是个好主意。

JSX 是在反应式框架中进行 UI/UX 开发的一个令人难以置信的想法,无论语言如何。 如果我有更多的空闲时间,我会推出 LSX,它是 JSX for Logo ;)

我不明白为什么两种语言会比一种更好。

您可以使用 Objective-C 和 Swift(2 种语言)对 iOS 进行编程
您可以使用 Java 和 Kotlin(2 种语言)对 Android 进行编程
...

我还没有看到支持 JSX 的论据。
上面的讨论只包含诸如“它更好”、“它提高了生产力”或类似的论点,但没有争论它为什么如何实际上比纯 Dart 代码更好,特别是考虑到计划的语言更改会减少类似 JSX 和
更纯的 Dart 代码。

@cbazza

您可以使用 Objective-C 和 Swift(2 种语言)对 iOS 进行编程
您可以使用 Java 和 Kotlin(2 种语言)对 Android 进行编程

这与 JSX 讨论有什么关系? 这怎么能算是优势呢?
你可以在 iOS 上使用 Swift,因为它是 Objectiv-C 的继承者。
您可以在 Android 上使用 Kotlin,因为它被认为是对 Java 的巧妙改进。
听起来您认为 JSX 应该取代 Dart。 这对我来说没有多大意义。

@zoechi

这与 JSX 讨论有什么关系? 这怎么能算是优势呢?
你可以在 iOS 上使用 Swift,因为它是 Objectiv-C 的继承者。
您可以在 Android 上使用 Kotlin,因为它被认为是对 Java 的巧妙改进。
听起来您认为 JSX 应该取代 Dart。 这对我来说没有多大意义。

您确实说过(JSX 是对当前方式的巧妙改进),但得出了错误的结论(JSX 取代了 Dart)。

@cbazza这只是更多相同

与普通 Dart 相比,实际优势是什么?

“JSX 是一个巧妙的改进”只是没有任何说服力,也不是论据。
这只是个人意见,没有(再次)任何论据来支持它,
与上面的其他 pro-JSX 参数类似。

如果你不愿意提供好的论据,你就不能指望任何人考虑你的建议。

将 JSX 之类的东西添加到 Dart 会导致 Flutter 工具和 IDE 中的大量工作和复杂性。 您需要为其他人提供适当的论据,甚至考虑查看它。

@zoechi听起来像是一个要求“好的”论点的破纪录,之前已经给出了很多,但你只是没有得到它; 没关系,“各有各的”。

将 JSX 之类的东西添加到 Dart 会导致 Flutter 工具和 IDE 中的大量工作和复杂性。 您需要为其他人提供适当的论据,甚至考虑查看它。

不是真的,我的工作几乎准备好了,考虑到我只在周末工作,我花了很少的时间。

同样,DSX 只是人们可以选择使用或不使用的巧妙改进,因为它不会改变当前的方式,它只是提供了其他人(React 开发人员)会立即熟悉的替代方案。

@cbazza

给了很多

并不真地。 只是一般性的主张,可能是真的,也可能不是。
没有提供允许其他人验证的其他详细信息。

不是真的,我的工作差不多准备好了

伟大的。 那么 Flutter 团队就不需要做任何事情了,问题就可以关闭了;p
这是否包括在 Flutter 支持的所有 IDE 中支持自动完成和语法检查?

伟大的。 那么 Flutter 团队就不需要做任何事情了,问题就可以关闭了;p

;)

这是否包括在 Flutter 支持的所有 IDE 中支持自动完成和语法检查?

大多数 IDE 已经支持 XML 和 JSX,因此添加我的小添加对他们来说并不难。

我想知道 JSX 语法在 angular Dart 中是否更受欢迎? 它似乎更像是一种你习惯的情况,而不是“更好”。 对于 Web 开发人员来说,JSX 语法可能感觉更自然。

我知道即使一天只使用不同的代码突出显示颜色,编程对我来说也很尴尬。

https://blog.dantup.com/2014/08/you-have-ruined-html/

是的,Angular 的人会非常喜欢 JSX,但 React Native 开发人员也会很舒服,这是针对移动开发的。 JSX 肯定不会被当前的 Flutter 开发者采用,但第二种选择会吸引新的开发者加入 Flutter,这是肯定的。

上面的文章大错特错,没有 JSX 的 React 基本上是不存在的,所有的响应式 Web 框架都允许在其 DSL 上混合标记和编程。

时代已经到来...
我非常高兴地宣布在线 DSX 转译器
https://spark-heroku-dsx.herokuapp.com/index.html

转译器 cbazza 做得很好
我想说的一件事是更容易理解 JSX 是结束标签。 我之前提到的想法:
想法:自动生成的结束标签

在您的第一个示例中,将给出 (removed the optional new in future Dart) 的颤振代码:

Material(
  child: Column(
    children: <Widget>[
      MyAppBar(
        title: Text(
          'Example title',
          style: Theme.of(context).primaryTextTheme.title,
        )-Text,
      )-MyAppBar,
      Expanded(
        child: Center(
          child: Text(
            'Hello, world!',
          )-Text,
        )-Center,
      )-Expanded,
    ],
  )-Column,
)-Material;

@cbazza我感谢您为社区和想要以这种方式构建 UI 的人们所做的工作,但我真的希望我永远不会被迫在 Flutter 中使用类似的东西:-(((

作为 Flutter 的新手,但对 React 非常熟悉,有几件事让我印象深刻:

  • 状态管理模型几乎相同
  • 小部件/组件虚拟渲染树几乎相同
  • 了解了状态和组件模型,我现在基本上已经准备好编写一个应用程序了,除了一些 Dart 细节和平台 API,但是......
  • 样式语言是一个绊脚石。 我指的是https://flutter.io/web-analogs/但要弄清楚需要哪些导入才能使事情正常工作(EdgeInset?颜色?)或者何时应该使用原语而不是类实例并不容易。
  • @cbazza的 DSX 转换器中的 CSS 解析器对于找出 Flutter 模型中的等效布局非常有用。

关于 JSX:

  • 我认为没有必要发明新的 JSX 语法来支持 Flutter 模式。 这个线程中的一些语法问题可以使用一些较新的 React 模式来解决,例如高阶组件(构建组件类的函数)和渲染道具(将函数作为参数的组件;函数返回元素)。 例如,命名为“子槽”可以在 JSX 中转换为类似这样的内容:
<Item
  right={() => new Text("Right")} {/* a named slot */}
  left={() => new Text("Left")}> {/* another named slot */}
  <ChildOne /> {/* generic children prop with 2 children */}
  <ChildTwo>
    <NestedChild />
  </ChildTwo>
</Item>
  • 我看到的反对 JSX 的最佳论据是 Dart 已经命名了参数。
  • 为什么一个元素知道它有多个孩子还是一个孩子很重要? 也许“片段”构造可以消除该 API 的歧义。

我仍然认为,作为一个在 Angular、React 等方面有一定经验的 Flutter 新手,常规的 Dart 方式,以及 Dart 2.0 中的更多方式,比这个 DSX 更好。 它只是比一些 XML 和 CSS-ish 参数更有意义。 🤷‍♂️

@cbazza您的第二个演示示例与 dart 的 391 个字符相比有 466 个字符(都没有空格)。 对我来说,它看起来很臃肿。 我必须学习它的语义,而我不需要使用普通的 Dart 代码。 而且我不知道如何使用通用编程范式(if、forEach 等)。

如果我有选择,我会坚持现在的模式。

每个人都只是在比较两种语法时给出自己的主观意见,但我们必须同意一个事实:这是一个非常有争议的功能。 有爱也有恨,但大多数人对 JSX 优于普通 Dart 的看法存在分歧。

无论如何,我认为要求 Flutter 团队在 1.0 发布之前承诺支持该功能是完全不合理的。 虽然当前构建 UI 的方式可能并不适合所有人——但它确实有效(并且在某些观点中效果很好)。

如果人们现在真的想要类似 JSX 的语法,那么社区驱动的努力似乎是要走的路。 当 Flutter 团队在 1.0 后版本中考虑它时,这将有助于证明(或不证明)。

就我个人而言,我非常同意以下论点:并不是因为 JSX 适用于 React(您已经在使用标记语言构建 UI),它会自动适用于 Flutter。

@tehfailsafe

好消息是,即使这是 Flutter 团队采用的(不太可能基于此线程),也没有人会被迫使用它。 这是一个选项。 我不明白为什么有些人可能喜欢用你不喜欢的语法编写代码时如此情绪化...

我不在乎别人喜欢什么不喜欢什么。 但我关心帮助我在申请中取得进展的功能。 资源有限,我宁愿拥有合适的视频/流播放器、原生子视图和一些矢量图形格式。

例如,现在在 React 和 React Native 中,您可以在没有 JSX 的情况下编写整个应用程序,这只是一种选择。 这是没有 JSX 的 React 的样子:
[...]
它比 JSX 版本要混乱得多,几乎没有人使用它。 这可能就是为什么我们中的一些来自 React 的人会欣赏避免再次使用这种风格的可能性。

那是因为网络不是为这样的系统设计的。 如果你有一个像 HTML 这样的静态标记语言并且想要“动态化”它,你必须发明一个需要在它之上工作的系统。 你最终会得到一些受底层平台约束的结构。
(见:https://gbracha.blogspot.de/2014/09/a-domain-of-shadows.html)

另一方面,Flutter 没有标记语言。 我还没有看到有理由将资源投入到缺乏活力和表现力的事物上。

我想知道不同意它的人是否在有和没有 JSX 的情况下使用过 React。 我鼓励每个人都尝试一下,这样这个讨论就不那么理论化了。 在最初的浅学习曲线之后,它变得非常自然(而且不仅仅是字符数,因为结束标签让您更容易阅读)。 这与学习其他新事物没有什么不同,比如 Flutter,从长远来看,它可以提高生产力。 我同意它并不适合所有人,这就是为什么它是可选的。
我认为重要的是要记住,我们牢记彼此的最大利益——让构建东西变得更容易。 我认为这个转译器会有所帮助,如果有官方支持,它会更容易采用。

另外,谢谢@cbazza :)

@yuriy-manifold

我认为这里没有人怀疑 JSX React 是对经典 React 的改进。 但就像我说的那样,该解决方案是由于与底层平台的属性相关的问题而创建的。 Flutter 没有这些属性。

问题不是“JSX 对 React 有帮助吗?” 问题是“像 JSX 这样的东西对 Flutter 有帮助吗?”。

我认为答案是否定的。

还有一些其他的事情需要考虑:

  • 将布局规范与应用程序代码分开可以使代码更具前瞻性; 例如,如果build方法根据可升级的编译指示从 JSX 等不可知格式转换为 Dart 代码,则此 Dart 2 语法建议不会影响这些方法。
  • 将布局定义为标记可以将渲染引擎与(有状态/虚拟化)小部件引擎分离,例如 React 与 ReactDOM 和 React Native 的关系,从而可能更容易将小部件移植到新平台。
  • 定义标记格式可以更轻松地将现有布局移植到 Flutter,例如从 Sketch 或其他设计工具

转译器 cbazza 做得很好

@Rockvole ,谢谢。

我感谢您为社区和希望以这种方式构建 UI 的人们所做的工作,但我真的希望我永远不会被迫在 Flutter 中使用类似的东西:-(((

@zoechi ,谢谢。 是的,它只是喜欢 JSX 的人使用的另一种选择。 如果那不是你喜欢的事情,那就继续做你正在做的事情,那里没有任何变化。

我认为没有必要发明新的 JSX 语法来支持 Flutter 模式。

@alexkrolick ,是的,您可以将渲染道具用于命名参数,但您对位置参数无能为力。 关键是我不想在转译器中硬编码任何东西,以便它适用于一切。

我仍然认为,作为一个在 Angular、React 等方面有一定经验的 Flutter 新手,常规的 Dart 方式,以及 Dart 2.0 中的更多方式,比这个 DSX 更好。 它只是比一些 XML 和 CSS-ish 参数更有意义。

@tenhobi ,很好用,显然 DSX 并不适合所有人。

如果我有选择,我会坚持现在的模式。

@b-strauss,这不是替代品,它是喜欢 JSX 的人的选择。

有爱也有恨,但大多数人对 JSX 优于普通 Dart 的看法存在分歧。

@lukaspili ,DSX 适用于热爱 JSX 的 React Native 人,如果您看不到它的好处,请不要使用它。 这不是 DSX 与普通 Dart 的区别。 这是 DSX 与 JSX,两者越接近越好。

好消息是,即使这是 Flutter 团队采用的(不太可能基于此线程),也没有人会被迫使用它。 这是一个选项。 我不明白为什么有些人可能喜欢用你不喜欢的语法编写代码时如此情绪化...

@tehfailsafe ,感谢您的收听!!! 你一针见血了,为什么会有这么大的阻力让 React Native 的人真正高兴。

我不在乎别人喜欢什么不喜欢什么。 但我关心帮助我在申请中取得进展的功能。 资源有限,我宁愿拥有合适的视频/流播放器、原生子视图和一些矢量图形格式。

@b-strauss,一旦 React Native 的粉丝转向 Flutter,就会有大量的人来帮助解决这些其他需要的事情。 优先级 1 是从 React Native 中窃取思想份额,并让 React Native 人尽可能简单地迁移。

另一方面,Flutter 没有标记语言。 我还没有看到有理由将资源投入到缺乏活力和表现力的事物上。

@b-strauss,DSX 与普通 Dart 相比,“动态性”和“表现力”如何? DSX 是 Dart 你没试过转译器。

@yuriy-manifold,谢谢。

问题不是“JSX 对 React 有帮助吗?” 问题是“像 JSX 这样的东西对 Flutter 有帮助吗?”。

@b-strauss,当然是。 它对当前的 Flutter 开发人员没有帮助,但对于可以从他们的工具中输出 CSS 的设计师来说非常有帮助,对于归属于 React Native 平台的人来说非常有帮助。

@alexkrolick ,非常好的观察。

@cbazza

这不是替代品,它是喜欢 JSX 的人的选择。

我明白了......它不会以那种方式影响我,但正如我之前所说,现在缺少一些我需要创建一个颤振应用程序的功能。

一旦 React Native 的粉丝转向 Flutter,就会有大量的人来帮助解决这些其他需要的事情。 优先级 1 是从 React Native 中窃取思想份额,并让 React Native 人尽可能简单地迁移。

所以你建议 Flutter 团队应该暂停一些有问题的功能,并且可能会或可能不会吸引一小部分特定的 Web 开发人员?

与普通 Dart 相比,DSX 的“动态性”和“表现力”如何? DSX 是 Dart 你没试过转译器。

根据定义,每个 DSL 都比 GPL 表达力要低。 使用 DSX 如何有条件地隐藏小部件? 如何遍历集合并将每个元素映射到小部件? 如何使用开关? 您现在必须为 GPL 中已有的结构构建语法和语义。 那么为什么首先要发明 DSL 呢?

当然是。 它对当前的 Flutter 开发人员没有帮助,但对于可以从他们的工具中输出 CSS 的设计师来说非常有帮助,对于归属于 React Native 平台的人来说非常有帮助。

那不是问题... DSL 可以解决哪些您现在无法解决的问题? 你一直说它更好,为什么它更好? 我毫不怀疑 DSX 会吸引一些 JSX 人。 我知道人们不喜欢与众不同的东西。 熟悉似乎是唯一的论据。 那么为什么不使用 CSS 呢?
为什么不使用 JavaScript? 比 Dart 更多的人知道如何使用这些。

如果你只是为了熟悉而基于其他东西来设计你的系统,那么你并不是真正的创新。

@b-strauss 要明确,JSX 编译为函数调用(在对createElement(ComponentClass)的 React 调用中,在 Dart 中它应该是构造函数)。

<A property="a" />
new A(property: a)
<A property="a">
  <B />
  <C />
</A>
new A(property: a, children: <Widget>[new B(), new C()])

唯一的构造是元素名称+属性和函数调用+参数之间的转换,以及转义表达式( {...} )。

  • 使用 DSX 如何有条件地隐藏小部件?
(JS)
  { condition && <A /> }
  { condition ? <A /> : <B /> }
  • 如何遍历集合并将每个元素映射到小部件?
(JS)
  { ['a', 'b'].map(i => <A property={i} />) }
  • 如何使用开关?
    据我所知,在 Dart 和 JS 中一样,您不能使用内联开关,因为它不是表达式。 如果您在小部件树之外,则可以正常使用开关。

所以你建议 Flutter 团队应该暂停一些有问题的功能,并且可能会或可能不会吸引一小部分特定的 Web 开发人员?

@b-strauss,React Native 不是 Web 开发,它是跨平台移动开发,是 Flutter 的主要竞争对手; 是的,JSX 就像一个光源,它会吸引很多 React Native 开发者。 我在 2017 年 8 月要求提供此功能,说太多,行动太少。

根据定义,每个 DSL 都比 GPL 表达力要低。 使用 DSX 如何有条件地隐藏小部件? 如何遍历集合并将每个元素映射到小部件? 如何使用开关? 您现在必须为 GPL 中已有的结构构建语法和语义。 那么为什么首先要发明 DSL 呢?

你完全错了。 好消息是我曾经也错了。 大多数(但不是全部)DSL 尝试在标记中重新创建编程结构(这不是很强大),JSX 将标记带入编程(充分利用宿主语言)。 区别在于转型。 你所有问题的答案基本上是使用你在 Dart 中的方式,因为它是 Dart。 '{}' 之间的所有内容都是 Dart 代码,扩展运算符除外。 这都是 dart 表达式,但您也可以使用返回表达式的匿名函数。 正如您在转译器中看到的那样,标签 (\) 只是一个新的小部件 (new Text())。

DSL 可以解决哪些您现在无法解决的问题?

当你可以使用 0 和 1 时,为什么还要使用 Dart,这难道不是解决任何计算问题所必需的吗?

你一直说它更好,为什么它更好?

我之前已经给出了我的理由,在此不再赘述。 JSX 的人会同意我的观点,但会“各自为政”。

我毫不怀疑 DSX 会吸引一些 JSX 人。 我知道人们不喜欢与众不同的东西。 熟悉似乎是唯一的论据。 那么为什么不使用 CSS 呢?
为什么不使用 JavaScript? 比 Dart 更多的人知道如何使用这些。

是的,使用 CSS 可以简化设计人员-开发人员的工作流程。 DSX 支持这一点。 Dart 相对于 Javascript 的优势在于执行速度(性能)。

如果你只是为了熟悉而基于其他东西来设计你的系统,那么你并不是真正的创新。

你充满了错误的偏见,很可能会阻止你充分发挥潜力。 敞开心扉,尝试不同的事物。

@alexkrolick ,感谢您提供详细信息。

@cbazza

你充满了错误的偏见,很可能会阻止你充分发挥潜力。 敞开心扉,尝试不同的事物。

我现在将退订这个问题。 请不要再在这里或任何地方提及我,谢谢。

@b-施特劳斯

对不起,伙计,我不是故意要伤害你的感情……我只是想温柔地引导你,同时努力控制自己的挫败感。 毕竟我们都是人。

@cbazza你能给我发一封电子邮件吗? [email protected]

已经在旧线程中提出了这个建议,但我仍然认为这是很重要的一点

恕我直言,无需使用new/const已经有很大帮助。 我在飞镖格式格式化树的方式上遇到了真正的困难。 与以下相比,它没有足够强调树结构恕我直言:

    return Scaffold(
      appBar: AppBar(title: Text("WeatherDemo")),
      resizeToAvoidBottomPadding: false,
      body: 
        Column(children: <Widget>
        [
          Padding(
            padding: const EdgeInsets.all(16.0),
            child: 
            TextField(
                    key: AppKeys.textField,
                    autocorrect: false,
                    controller: _controller,
                    decoration: InputDecoration(hintText: "Filter cities",),
                    style:  TextStyle(fontSize: 20.0,),
                    onChanged: ModelProvider.of(context).textChangedCommand,
                    ),
          ),

我同意为了让flutter变得简单,不想使用类似JSX的语法,并且我也支持拆分为多个小部件的概念,但现在它让我感觉就像在jquery中回到了MVC时代。 这样的场景有一个简单的widget,后面有padding,border和center layout,很多“}”符号严重影响可读性。但是,它是一个整体widget,我不想拆,有什么用解决方案? 虽然我的英语很差,但我努力表达我的想法。

主帮助我们所有人。

好的,这无济于事。 看起来没有人会很快改变立场。 我们肯定需要在这里达成某种妥协。 当然,“pro-DSX”与“anti-DSX”并没有真正令人满意的妥协,这是一个令人沮丧的认识。 我们是否可以重新构建我们的立场,使它们更加兼容?

@naiveaiguy “他们”可以拥有他们的 DSX。
如果 Flutter 团队没有实现它,它可以是一个开源计划。
这并不意味着像现在这样的纯 Dart 方法将不再适用。
两个世界可以共存。

我非常同意@zoechi他们可以共存......就是这样,我认为这已经解决了旧线程

@lrhn

请大家保持文明和建设性。 我们在这里讨论风格,这是一个非常主观的东西,所以无论每个人多么喜欢自己的喜好,它都不太可能天生就优于其他人。 请列出您在现有和建议的语法中看到的优点和缺点,但请记住,并非每个人都以相同的方式看待它,这很好。

太棒了,绝对是这样。

在 React 中,你可以通过 4 种方式来实现(我今天刚刚发现了另外 2 种方式!!!)

(1)你可以使用JSX(这是我喜欢的)
https://reactjs.org/docs/introducing-jsx.html

(2)可以使用原来的方式(类似于Flutter)
https://reactjs.org/docs/react-without-jsx.html

在上面链接的末尾,他们甚至提到了 2 个有前途的社区项目

(3) React.js 标记的超脚本语法
https://github.com/mlmorg/react-hyperscript

(4) 上标的简洁语法。
https://github.com/ohanhi/hyperscript-helpers

有替代品是一件好事,只要是黑色,你就可以买到任何你喜欢的颜色的福特汽车的日子已经一去不复返了:)

@naiveaiguy如果有当前的方法DSX,为什么这对您来说是个问题?
(这就是我从你的反对票中得出的)

@naiveaiguy “他们”可以拥有他们的 DSX。
如果 Flutter 团队没有实现它,它可以是一个开源计划。
这并不意味着像现在这样的纯 Dart 方法将不再适用。
两个世界可以共存。

我完全同意这一点。 虽然我认为它应该是一个可插拔的而不是开箱即用的解决方案。 拥有一个可行的标准,但能够使用额外的东西定制体验是一个很好的范例。 这样,Flutter 团队可以将注意力集中在(我认为是)更相关的问题上,社区可以尝试不同的工具/解决方案,然后我们可以就 DSX 或当前任何其他替代方案的更多数据和经验进行讨论元。

有替代品是一件好事,你可以买到任何颜色的福特的日子已经一去不复返了
喜欢,只要它是黑色的 :)

诚然。 但是,我认为我们都同意我们不希望 Dart/Flutter 成为另一个 JS/Web 前端生态系统。 Flutter 甚至还没有结束测试,我们已经希望它有 2 个标准来处理一些主观的东西。

在 React 中,你可以通过 4 种方式来实现(我今天刚刚发现了另外 2 种方式!!!)

尽管 React 引用了它们,但大多数都是社区驱动的。 中途好。 现在,官方只支持其中的两种: React.createElement和 JSX 方式,它是对另一种方式的封装。 JSX 的价值在这种情况下是臭名昭著的,但在这里还不是很清楚。 考虑到这一点,我们是否可以通过只有一个官方标准和相关文档引用 DSX 来中途满足?

我认为 Flutter 团队应该专注于真正阻碍开发人员构建应用程序的缺失功能。 如果我们甚至无法添加地图支持并且开发相机功能需要 2 周时间,我就不能向我的经理推荐 Flutter。

请记住,我不会永远关闭 DSX 的大门。 也许它将成为 UI 构建的解决方案,但我们需要社区对其进行试验才能做出决定。

@zoechi 就我个人而言,我不相信这两种想法可以在 Flutter 的当前状态下共存——我们真的不应该这么早就鼓励这种性质的分裂——但在这一点上,它看起来是唯一的妥协。

@naiveaiguy

就个人而言,我不相信这两种想法可以在 Flutter 的当前状态下共存——我们真的不应该这么早就鼓励这种性质的分裂

您能否更具体地说明它们为什么不能共存? (鉴于 DSX 只是合成糖这一事实;或者正如@emalamela所说的“只是当前方式的包装器”)。

另外,为什么为完全相同的事物提供不同的语法还为时过早? 我基本上是在问为什么需要推迟这个,未来会有什么不同,现在还没有?

@emalamela

但是,我认为我们都同意我们不希望 Dart/Flutter 成为另一个 JS/Web 前端生态系统。

就我个人而言,我宁愿不限制人们可以使用 Dart/Flutter 做什么。 让市场/社区来决定。 基本上,如果创造的东西没有增加价值,人们就不会使用它,它就会消亡。 如果它变得流行,那是因为社区发现它有用并重视它。 现在不需要选择赢家和输家。

唯一阻止我尝试 Flutter 的是他们选择不使用 JSX。
恕我直言 JSX 是表达组件层次结构的最佳选择

听说过 Flutter,想尝试一下,甚至考虑到我看到语法的那一刻,就立即停止了,这很遗憾,因为这很可能是一项伟大的技术。 构建产品。

在过去的 2.5 年里,我一直在进行 React/React Native 开发,在描述 UI 时要牺牲 JSX 语法提供的生产力,这是一个很大的问题。 我会认真考虑花时间学习有关 Flutter 的所有知识,并研究是否值得在开箱即用的情况下支持此类功能。

我什至无法想象 Flutter 正因此而失去的潜在采用者/用户/开发者的数量,将在接下来的几个月中重新审视。

我什至无法想象 Flutter 正因此而失去的潜在采用者/用户/开发者的数量,将在接下来的几个月中重新审视。

是的,44 Mio发现它甚至足以支持:D

是的,44 人发现它甚至足以支持投票:D

当按“upvote”排序时,此功能请求在 3131 个已打开票证的列表中排名第 7。

https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc

@cbazza我不想反对这个功能,但是像“如果你不做 x 那么可怕的 y 会发生”这样的评论简直是荒谬的。

在过去的 2.5 年里,我一直在进行 React/React Native 开发,在描述 UI 时要牺牲 JSX 语法提供的生产力,这是一个很大的问题。 我会认真考虑花时间学习有关 Flutter 的所有知识,并研究是否值得在开箱即用的情况下支持此类功能。

@sonaye

既然你提到了生产力,你能提供一个例子来清楚地展示使用 Flutter 的 Pattern 而不是 JSX 的生产力损失吗? 该示例应该在了解足够的 JSDart 的基础上构建,以便能够编写该示例。 我相信如果我们不考虑这一点,那么我们也在比较编程语言,这不是同一个讨论。

当按“upvote”排序时,此功能请求在 3131 个已打开票证的列表中排名第 7。

@cbazza

它也是投票最多的一个。 这是相当有争议的。

@emalamela

它也是投票最多的一个。 这是相当有争议的。

由于此功能请求是当前方式的替代方案,并且不会改变当前方式,因此根本不应该有任何争议; 如果您不喜欢 JSX/DSX,请像今天一样继续编程。

之所以存在所谓的争议,只是因为 Flutter 团队需要做一些工作,让社区能够正确地做 DSX。 如果 Flutter 工具(编译器、分析器、ide 支持等)支持使用源映射进行预处理,那么 DSX 早就完成了,并且很可能来自 3rd 方开发人员的其他语言创新/想法也会发生。

new Card(
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: <Widget>[
      AspectRatio(
        aspectRatio: 18 / 11,
        child: Image.asset('assets/diamond.png'),
      ),
      new Padding(
        padding: EdgeInsets.fromLTRB(16, 12, 16, 8),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text('Title'),
            SizedBox(height: 8),
            Text('Secondary Text'),
          ],
        ),
      ),
    ],
  ),
)

变成:

<Card>
  <Column crossAxisAlignment={CrossAxisAlignment.start}>
    <AspectRatio aspectRatio={18 / 11}>
      <Image src={asset('assets/diamond.png')} />
    </AspectRatio>

    <Padding padding={EdgeInsets.fromLTRB(16, 12, 16, 8)}>
      <Column crossAxisAlignment={CrossAxisAlignment.start}>
        <Text>Title</Text>
        <SizedBox height={8} />
        <Text>Secondary Text</Text>
      </Column>
    </Padding>
  </Column>
</Card>

@emalamela支持和反对 JSX 的争论已经被讨论过,有很多材料可以查找。 我只是分享我的个人观点。

首先,代码可读性。 我可以立即对 JSX 中的 UI 结构有一个清晰的概念(需要几秒钟),思维模式非常直观。 第二,可用性。 我认为即使不了解 JS/Dart 或任何有关底层 API 的知识,也可以使用 JSX。 这非常适合刚刚学习编程的人,或者对于我团队中的一些人,设计师现在可以编写UI。

应用程序的描述完全是声明性的(不仅仅是表达性的),当你处理一个包含数百个组件的大型项目时,这种描述 UI 的方式会产生巨大的差异(你必须尝试它才能真正体会到它)。 我第一次看到 JSX 的时候也不喜欢它,用过之后感觉很好,这就是我从现在开始想要描述 UI 的方式,这在我构建界面的方式上是一个明显的突破。

这不是关于编写更少的代码行,也不是关于拥有“语法糖”,而是关于为人类构建工具。 我也反对每个人都应该使用 JSX 的说法,这太荒谬了。 你使用的工具可以让你更快地完成工作,减少混乱,在很多人(包括我自己)的情况下,它会是 JSX(或者在 Flutter 的情况下是 DSX),仅此而已。

我来自 React,第一次尝试 Flutter。 Flutter 团队没有 JSX 语法真的很奇怪,我是认真的! 在 JS 世界中,JSX 现在在每个 React-alternatives 中都非常流行! JSX 对开发人员非常友好。 请尽快实施,以便您帮助社区发展。

您可以通过查看此问题中的评论数量来判断 JSX(或本例中的 DSX)是一个大问题。

JSX 是你不知道自己喜欢的东西,直到你尝试它。 一开始在你的代码中有标记很奇怪,但后来它变得很棒。

对于已经知道颤振/飞镖的人来说似乎没有必要,我明白了。 但是对于从未接触过 dart 的人(比如我自己)来说,JSX 更容易上手,这就是重点。 如果你们希望更多的人过来并开始构建更多很棒的东西,那么工具需要更容易。

而且,正如@eseidelGoogle (https://youtu.be/h7HOt3Jb1Ts?t=2m41s) 告诉另一个人“Flutter 是一种在单个代码库中写入 iOS 和 Android 的方式。我们试图让它变得快速和简单[. ..] Flutter 一直讲到硬件 [...] 我们有一个非常分层的方法,所以您可以随心所欲地使用。[...] 我们在工具方面进行了大量投资。”

请实现 JSX。

我是 Dart 的粉丝,也是 react 的重度用户。 我总是发现 Dart 比 JSX 更简洁,更易于维护。 所以,我认为 JSX/DSX 可以而且也许应该以社区的方式实现。

@rajaraodv仅仅因为 Flutter 被提升为响应式风格框架并不意味着它只是 ReactJS 的一种风格。
从大多数评论中,我得到的印象是人们很难接受新事物与他们已经知道的事物不同。

您可以尝试使用 Flutter 的现状一段时间,然后提供适当的论据,说明为什么您认为 JSX/DSX 会比普通的 Dart 更好,而不是仅仅“因为个人喜好”或“因为它更好” .

@zoechi ,你错过了一些东西:根据 Flutter 文档,flutter 的灵感来自 React。
也许这只是我的问题。 我真的觉得我很难阅读 UI 代码,即使它是 Dart 2 语法。

Flutter 的灵感来自 React Native

我不明白这怎么说“除了语言被称为 Flutter 而不是 JS 之外,一切都是一样的”。

真的觉得看UI代码有点吃力

你声称唯一可以想象的解决方案是 DSX?

您是否考虑过 Flutter 甚至不是 1.0 并且 IDE 支持会随着时间的推移而改进?

为了在代码编辑器中获得更好的 Flutter IDE 支持,最近只采取了最初的小步骤,例如快速修复(“wrap xxx”)和关闭标签。

改善开发者体验的可能性是无限的,在这个讨论中,大多数都是这样的
“Flutter 还不完美,因此我们需要 DSX”
通常没有关于 DSX 如何或为何解决或改进该问题的具体论据。

@zoechi

您可以尝试使用 Flutter 的现状一段时间,然后提供适当的论据,说明为什么您认为 JSX/DSX 会比普通的 Dart 更好,而不是仅仅“因为个人喜好”或“因为它更好” .

再一次,Plain Dart 或 DSX 只是风格问题,没有必要争论哪个更好。 这只是个人喜好,人们有他们选择其中一个的理由。

在 React 世界中发生的事情是,一旦你使用 JSX,你就再也回不去了。 正如其他人在上面所说的那样,您在使用一段时间后就会迷上 JSX。 JSX 已被 React 世界之外的其他人(Typescript、Vue)采用,它非常适合 Flutter。

你声称唯一可以想象的解决方案是 DSX?

社区需要的是通用的预处理功能,以及内置在 Dart 工具(编译器、分析器、IDE 等)中的源映射支持,以便社区可以开发 DSX 或更好的东西并完全集成到 Flutter(调试器、自动完成等)。

改善开发者体验的可能性是无限的,在这个讨论中,大多数都是这样的
“Flutter 还不完美,因此我们需要 DSX”
通常没有关于 DSX 如何或为何解决或改进该问题的具体论据。

当然,问题是这张票不是关于一般的“改善开发人员体验”的事情。 它非常具体,是关于在 Flutter 中获得 JSX 支持。 社区希望 DSX 作为普通 Dart 方式的替代品。

我看不到自己在使用它(但我愿意尝试一下)。 我不认为这是灵丹妙药,但有如此多的热情值得做。

我认为谷歌应该消除语言障碍,让社区建立他们想要的东西。

我不知道有任何障碍阻止 Google 的 Flutter/Dart 团队以外的人为 Dart/Flutter 编写类似 JSX 的东西。 如果有人在尝试,我很乐意看到那些错误。 (也有可能我在上面的评论中错过了它们,因为我承认没有阅读这个很长的错误的每一个字。):)

谢谢! 很高兴看到这样的热情!

@eseidel谷歌

Intellij 和/或 VS Code(使用 Dart-Code)如何设置断点并单步执行 .dsx 文件中的代码? (我的意思是这不是 .dart 文件)。 .dsx 文件(与 .dart 文件一样)的自动完成功能怎么样?

您在工具上投入了大量资金,但该工具不支持无缝转换为 Dart/Flutter 的新语言(如 DSX)的预处理(使用源映射)。

可以使用转译器,但没有简单的方法可以完全集成它:
https://spark-heroku-dsx.herokuapp.com/index.html

PS这张票只是评论的一半!!!
https://github.com/flutter/flutter/issues/15922

@cbazza在某个地方有那个编译器的回购吗? 分享代码并让社区参与破解它会很棒,即使它并不完美。

@jonahwilliams ,没有 DSX 转译器代码尚未发布,因为现在还为时过早。
您可以简单地使用 2 个手写等效文件(.dsx 和 .dart)来测试断点、步进、自动完成等预处理功能。

一旦工具支持使用某种源映射进行预处理,我就可以将其添加到转译器中并被解除阻塞。 这也将使其他人能够试验他们内心的渴望。

我不在 Flutter 上工作,但要求某些工具来造福他人似乎有点不合理,但同时又拒绝发布任何早期源代码或您希望工具与之集成的示例。

对于它的价值,我不知道有任何语言或工具包提供任何类型的预处理钩子 - 可能是因为它很简单,有很多关于语言和语法的极端案例和假设。

如果您生成了源映射 (https://pub.dartlang.org/packages/source_maps),我想在 IDE 中至少获得一些基本支持是非常简单的,独立于 Dart/Flutter。 但同样,这都是猜测,不知道你的工具做什么以及你期望它如何工作。

@matanlurey ,通过源映射支持预处理是一种通用机制,不依赖于任何特定的转译器。 它的功能旨在支持任何未来可以想象的语言。 Chrome 浏览器/调试器很好地支持它,我可以调试任何转换为​​ JS 的语言。

为了进行测试,您可以提出任何简单的转译器来展示如何使用源映射。 例如,编写一个简单的转译器,生成 Dart/Flutter 代码,在原始文件的每一行之间有一个空行。 (.d2 => .dart,.d2 是 Dart/Flutter 文件,输出 .dart 文件将在原始文件的每一行之间包含一个空行)。

是的,我可以为测试文件生成源映射。

Flutter 目前不太愿意尝试取悦 NativeScript、ReactNative、Android、Web 等习惯类似 XML 布局的开发者。 他们有更重要的事情要做,所以我们解散并去睡觉吧。

我希望 Amy 的 JSX 语法支持者能在继续哀叹之前花几天时间真正使用 Flutter。 我来自基于 Xaml 的系统,但很快就习惯了。 试一试吧。

@escamoteur
嘿,escamoteur。 你是不是觉得我没有花很多时间学习 Flutter?
在 flutter.io/tutorials/layout/ 中,在“打包小部件”部分的末尾,教程提供的代码不起作用。
我在颤振问题块下提到了这个问题,但没有人愿意关心这个。

@JonathanSum您的评论与此问题的主题有什么联系吗?

@zoechi
escamoteur 说他希望 JSX 语法的支持者在继续哀叹之前花几天时间真正使用 Flutter。
这条评论说明我们真的花了很多天在 Flutter 上工作,对 JSX 的要求真的是我们发自内心的感受。

Group Dart: “Dart 语法更好,而 JSX/DSX 就是不好”
JSX/DSX 组: “JSX/DSX 语法要好得多,而 Dart 就是不好”

我不能是唯一一个看到这个的人吗? 双方都提出了支持和反对他们立场的有效观点。 我认为这里丢失的是@cbazza不仅有批评,而且还做了一些关于它的事情。 试图弥合 web devs/react/react-native 和 Flutter 之间的差距,以使 Flutter 受益。

还有我的 2 美分……作为一个全栈开发人员,我拥有多种语言和方法的 exp……JSX 是我最喜欢的代码编写方式之一,我确实希望 Darts 有另一种语法。 . 我并不是说当前的语法不好,只是我更喜欢 JSX 风格。

我不得不不同意来自Group JSX/DSX的这句话

飞镖不好

Dart 是一种非常好的和健壮的语言,没有人反对这种语言。 讨论的不是 Dart,而是它上面的合成层,大多数 UI 开发人员今天已经在使用,我们建议 Flutter 包含类似的东西。

  • Android 有 XML 布局。
  • iOS 有 Storyboard XIB (XML)
  • GTK+ 有用于 Pango 等的 XML。
  • Qt 有 QML(类似 YAML)
  • Xamarin 有 XAML

这些框架和语言中的大多数都具有将视图与控制器逻辑分开的 UI 标记语言。 然后 React 出现了不同的方法(我们在这里提出),我认为我们必须同意 RN 现在在用户增长和受欢迎程度方面正在飞速发展,我可能错了,但主要是因为 JSX。

...

真的是这么疯狂的提议,我们必须从 Flutter 团队/用户那里得到这种反馈吗?

@birkir和所有这些都带来了 Flutter 没有的许多麻烦 \o/
不需要另一种语言。
即使使用相同的语言,您也可以在 Flutter 中分离视图。

@birkir这个线程 100% 是关于 Dart 和语法的。

讨论的不是 Dart,而是它上面的合成层,大多数 UI 开发人员今天已经在使用,我们建议 Flutter 包含类似的东西。

所以这与 Dart 无关……但 Flutter 需要使用 Dart 之外的其他东西进行布局? 似乎您说 Dart 不够好,同时还声称这与 Dart 无关?

我认为此时这并不重要,Flutter 团队已经看到了这个反馈(关于请求 JSX/DSX 方法)并且他们希望继续他们原来的道路。 我确实认为它可以处理得更好,但他们似乎并不反对社区创建解决方案。

我很高兴还有另一个跨平台选项……Apple 会是下一个提供产品的吗? 也许他们会看到我们这么多人喜欢 react/react-native 什么? IDK,如果他们有任何烹饪。

Flutter 团队已经看到了这个反馈(关于请求 JSX/DSX 方法),他们

这个错误仍然存​​在,因为我们还没有弄清楚我们想要在这里做什么。 我们正在热切地研究这些实验(例如 cbazza 的),以了解人们如何使用它们。 我们计划在某个时候在构建系统中为诸如此类的代码生成工具提供一个挂钩,尽管这不是我们在不久的将来可能会做的事情。 从长远来看,我们希望利用我们在这里学到的东西来影响 Dart 作为一门语言的发展。 这可能意味着将 E4X/H4X/JSX/DSX 之类的东西添加到 Dart 本身。 或者也许我们会发现没有人真正最终使用它,所以我们什么也不做。 或者,也许每个人都需要不同的东西,所以 codegen 钩子和 cbazza 之类的自定义包就是答案。 我们还不知道。

@jstansbe - Apple 认为跨平台意味着 iPhone、iPad 和 Mac OS。 他们更有可能在有围墙的花园顶部添加炮塔,而不是跨平台建造东西:)

我认为如果有可能以其他方式缩进和格式化小部件,它会更类似于 jsx,并且对有 xml 和 html 经验的用户(几乎所有的 android 开发人员)更友好......在codelab中检查此代码

return new Container(
    margin: const EdgeInsets.symmetric(horizontal: 8.0),
    child: new Row(
      children: <Widget>[
        new Flexible(
          child: new TextField(
            controller: _textController,
            onSubmitted: _handleSubmitted,
            decoration: new InputDecoration.collapsed(
              hintText: "Send a message"),
          ),
        ),
        new Container(                                                 //new
          margin: new EdgeInsets.symmetric(horizontal: 4.0),           //new
          child: new IconButton(                                       //new
            icon: new Icon(Icons.send),                                //new
            onPressed: () => _handleSubmitted(_textController.text)),  //new
        ),                                                             //new
      ],
    ),
  );

检查这个飞镖到jsx代码

<Container margin="">
   <Row>
       <Flexible>
            <TextField   controller=""
                                onSubmitted=""
                                decoration="">
                 <OtherWidget></OtherWidget>

            </TextField>
        </Flexible>
   </Row>
</Container>

并与这种其他格式进行比较更htmlish

  return Container(margin: const EdgeInsets.symmetric(horizontal: 8.0), child:
            Row(children: <Widget>[
                Flexible(child:
                    TextField(controller: _textController,
                              onSubmitted: _handleSubmit,
                              decoration: new InputDecoration.collapsed(hintText: "manda un mensaje"),),
                    ),
                Container(margin: const EdgeInsets.symmetric(horizontal: 4.0),child:
                     IconButton(icon: Icon(Icons.send),
                               onPressed: ()=>_handleSubmit(_textController.text),),)
              ],
            )
    );

这有点相似,现在您只需要从左到右查看类似于 html/xml/jsx 的不同小部件

元素(小部件)属性比新的小部件有更多的缩进,所以这使得更清楚可以理解和检查代码

如果我可以在不同的 ide 上自动缩进这种格式,那就太好了,现在我是手动完成的......

在阅读了这里的所有评论并与我的朋友(原生移动应用程序开发人员,java/kotlin/objective-c/swift 家伙)私下讨论后,我的观察:

人们要求两件事,

  • __更好的可读性和更容易的写作__。 在当前的编码方式中,混合了一些语法噪音(括号、分号、 newchildchildren )的深度嵌套很烦人。
  • __从代码中分离样式/设计__。 视觉分离有利于阅读(一目了然地与命令式代码区分开来),而真正的分离有利于工具(例如,带有布局编辑器的 IDE)。

也主要有两个意见不同的群体,

  • 在不引入其他复杂性来解决问题的情况下改进当前语法。
    在这个方向上已经有了一些改进。例如,Dart 2.0 中的可选newconst和提出的virtual "closing tag" comments功能。
  • 引入额外的标记语言(类似 JSX 或类似 XML)来解决问题。

你不能轻易断定目前哪个更好。 因此,只需让社区先进行实验,然后再做出最终决定(接受或拒绝)。

@hooluupog虚拟结束标签注释已经在 IntelliJ、AS、VSCode 中工作了一段时间

@Hixie

这个错误仍然存​​在,因为我们还没有弄清楚我们想要在这里做什么。 我们正在热切地研究这些实验(例如 cbazza 的),以了解人们如何使用它们。

人们不能使用我的实验,因为它现在不能无缝嵌入到 Flutter 中; 所以它仍然是一个外部/在线实验,人们只能看到潜力。

我们计划在某个时候在构建系统中为诸如此类的代码生成工具提供一个挂钩,尽管这不是我们在不久的将来可能会做的事情。 从长远来看,我们希望利用我们在这里学到的东西来影响 Dart 作为一门语言的发展。

您能否在时间上更具体地说明我们何时可以预期构建系统更改会发生一些变化以支持预处理? 我们是在谈论一个月、一个季度、六个月、一年、两年、十年、一个禧年等吗?

这可能意味着将 E4X/H4X/JSX/DSX 之类的东西添加到 Dart 本身。

请阅读 JSX 规范的顶部段落,以了解不需要更改 Dart 语言,因为 JSX/DSX 没有语义,并且它并不意味着由引擎实现或合并到语言中。 它旨在用于预处理器(转译器)。 DSX 可以与 Flutter & on Web 一起使用,以使 React-Dart 与 React.js 完全一样,但使用的是 Dart 语言。

https://facebook.github.io/jsx/

或者也许我们会发现没有人真正最终使用它,所以我们什么也不做。

人们如何使用一开始无法使用的东西,然后得出结论,因为人们没有使用它,所以不需要做任何事情? 这让我想起了梅丽莎·麦卡锡(Melissa McCarthy)在 SNL 上扮演的肖恩·斯派塞(Sean Spicer)关于“旅行禁令”……“循环使用这个词”:)

https://www.youtube.com/watch?v=1Dvo6EHEJQE&t=48s

或者,也许每个人都需要不同的东西,所以 codegen 钩子和 cbazza 之类的自定义包就是答案。 我们还不知道。

非常需要预处理能力来进行实验。 没有它,什么都不会前进,你也不会学到任何新东西。

人们不能使用我的实验

我认为你低估了人们尝试事物的意愿,即使他们没有完全完善。 例如,有人可以很容易地编写一个包装flutter run的 shell 脚本首先进行预处理,然后调用flutter run 。 我自己有一个脚本,它包含热重载来做类似的事情(我首先运行分析器,然后只有当它通过时,我才会将热重载信号发送到flutter脚本)。

您能否更具体地了解我们何时可以预期构建系统更改会发生一些变化

不是真的(参见例如https://en.wikipedia.org/wiki/Forward-looking_statement了解为什么很难做出这样的陈述),但可能不会在未来几周内发生。

无需更改 Dart 语言

确实,这很有可能。 我只是说,基于这些实验,我们可以得出任意数量的结论,从“什么都不做”到“为语言语法添加激进的新特性”以及介于两者之间的任何结论。 关键是,我们还没有做出任何决定,并且非常愿意根据所有这些讨论和实验来了解需要做什么。

将 JSX 添加到 backlog 中,让它像角斗士一样与百万加一的其他紧急需求竞争?

React 是为 Web 编写的,因此需要一个简单的解决方案来编写 HTML。 JSX 流行起来并不是因为它是编写 UI 的最佳解决方案,而是因为它是编写 HTML 的最佳解决方案。

Flutter 没有这个限制,所以我们不应该因为错误的原因而接受一个平庸、冗长的解决方案。

如果我们想减少冗长,我宁愿从 Anko (https://github.com/Kotlin/anko/wiki/Anko-Layouts) 中获取灵感。 在那里,您可以在任何地方定义新的局部变量,并使用普通的 for 循环来动态构造子列表,这可以使代码更易于遵循。 此外,由于每个嵌套级别已经是一个 lambda 函数(无需传递额外的构建器 lambda),因此 LayoutBuilder 会变得更容易。 无论如何,这只是为了灵感,我认为 Flutter 不应该复制 1:1。

React 是为 Web 编写的,因此需要一个简单的解决方案来编写 HTML。 JSX 流行起来并不是因为它是编写 UI 的最佳解决方案,而是因为它是编写 HTML 的最佳解决方案。

React Native 不是 Web 开发,也不是使用 HTML。 询问有经验的 React 开发人员(或完全阅读本文和其他 JSX 线程),您会发现 JSX 被许多 React 开发人员认为是编写 UI 的最佳方式。

在那里,您可以在任何地方定义新的局部变量,并使用普通的 for 循环来动态构造子列表,这可以使代码更易于遵循。

这句话清楚地表明你不了解 JSX。 JSX(如在 DSX 中)使用来自宿主语言(Javascript/Dart)的所有编程结构(for-loops 等)。

此票仅对类似 JSX 的功能感兴趣,对于其他方法(如 Anko),请创建您自己的票以在那里讨论。

React Native 不是 Web 开发,也不是使用 HTML。 询问有经验的 React 开发人员(或完全阅读本文和其他 JSX 线程),您会发现 JSX 被许多 React 开发人员认为是编写 UI 的最佳方式。

React 早在 React Native 之前就出现了。 JSX 的原始设计基于渲染 HTML,而不是原生 UI。 对于 JSX 做得更好的地方,没有人能够提出一个令人信服的论据。 通过比较

new Scaffold(
  appBar: new AppBar(
    title: new Text(widget.title),
  ),
  body: new Column(
    child: ...,
  ),
)

<Scaffold
    appBar={<AppBar title={<Text>{widget.title}</Text>} />}
  >
  <Column>
    ...
  </Column>
</Scaffold>

您还没有进行最新的比较,而只是将更多的东西放在一行中。 您必须将其与以下内容进行比较:

Scaffold(
  appBar: AppBar(title: Text(widget.title)),
  body: Column(
    child: ...,
  ),
)

注意所有丑陋的{<{<>} />}和关闭</...>标记是如何消失的。

这句话清楚地表明你不了解 JSX。 JSX(如在 DSX 中)使用来自宿主语言(Javascript/Dart)的所有编程结构(for-loops 等)。

不,您不能在 JSX 中使用 if 语句或 for 循环(或 switch 或任何其他语句):

function render(data) {
  return (
    <div>
      // This is impossible
      let total = 0;
      for (let item of data.list) {
        total += item.value;
        <div>{ total }</div>
        <div>{ item.name }</div>
      }
    </div>
  )
}

只允许表达式。 因此,您必须使用条件运算符( c ? x : y ,这使得else if非常难看)和Array.map等(也可能非常难看)或将部分代码移动到渲染函数的顶部或单独的辅助函数。 当然,Flutter 也是如此。 Anko 没有这个限制,让编写(一些)UI 代码更加自然。

我认为在关于引入 JSX 的讨论中,询问这是否真的是最好的解决方案或者我们是否能找到更好的解决方案是非常有效和必要的。 否则我们会在错误的任务上浪费资源。

React 早在 React Native 之前就出现了。 JSX 的原始设计基于渲染 HTML,而不是原生 UI。

JSX 的最初设计是关于创建/操作在做 UI 工作时特别出现的树结构的熟悉方式; 想想出现在 Web 开发、本机开发、任何 UI 开发等中的组件层次结构 (https://facebook.github.io/jsx/)。

对于 JSX 做得更好的地方,没有人能够提出一个令人信服的论据。

这就是重点,我们并不是要替换当前的方式,而是要添加一种 React 开发人员熟悉的替代方式。

Android Kotlin 开发人员会熟悉您的 Anko 提案,因此请继续在单独的工单中提出适用于当前 Flutter 层次结构的规范。 一旦我看到(或尝试您的规范的在线版本),我将能够查看它是否可以生成/与当前的 Flutter 小部件层次结构互操作。

不,您不能在 JSX 中使用 if 语句或 for 循环(或 switch 或任何其他语句):

不是我建议你这样做,但它是可能的:创建一个匿名函数并调用它。

function render(data) {
  return (
    <div>
      { ()=>{
        // This is *not* impossible
        let divs=[];
        let total = 0;
        for (let item of data.list) {
          total += item.value;
          divs.push(<div>{ total }</div>);
          divs.push(<div>{ item.name }</div>);
        }
        return divs;
      }() }
    </div>
  )
}

我认为在关于引入 JSX 的讨论中,询问这是否真的是最好的解决方案是非常有效和必要的。

没有最好的解决方案,一切都是关于选择,选择使用直接映射到 Flutter 小部件并且不增加开销的熟悉的东西。

顺便说一下,在我的在线转译器上尝试以下操作:
https://spark-heroku-dsx.herokuapp.com/index.html

@<Scaffold>
  <appBar:AppBar>
     <title:Text [widget.title]/>
  </appBar:AppBar>
  <Column>
    {kids}
  </Column>
</Scaffold>@

你得到:

--------new Scaffold(
--------  appBar: new AppBar(
--------    title: new Text(
--------      widget.title,
--------    ),
--------  ),
--------  child: new Column(
--------    child: kids,
--------  ),
--------);

DSX 类似于 JSX,但对于 Dart 和 Flutter,它有自己的特性,如上面的链接所述。

当我看到这个时,我会从 Android 的 xml 布局中得到闪回。我认为实现这个不是一个好主意。 现在你甚至不必写newconst它甚至看起来更好。

@charafau你能分享一个例子/img/链接,“来自Android的xml布局”你指的是?

不,@wkornewald。 如果“JSX 之所以流行不是因为它是编写 UI 的最佳解决方案,而是因为它是编写 HTML 的最佳解决方案”,那么 React 为什么仍然使用 JSX 来构建移动应用程序和桌面应用程序? 甚至你的 Github 桌面应用程序、沃尔玛跨平台移动应用程序、Tesla 应用程序和 Skype 也是由 RN 构建的。

React 没有在 JSX 标签中放置 for 循环,因为 React 的概念是关于组件的。 上半部分是逻辑,下半部分是 JSX,一直都是这样。 一切都被分成许多组件,然后连接在一起成为一个大组件。

事实上,这里大多数反对 JSX 的人只能猜测 JSX 是某种 HTML、XML 或不那么冗长的解决方案。

@JonathanSum

这里大多数反对 JSX 的人只能猜测 JSX 是某种 HTML

我认为这是因为除了个人偏好之外,没有其他支持 JSX/DSX 的论据。 正如上面已经讨论的那样,这当然很好,但是请不要暗示人们反对 JSX,因为他们不理解它,因为没有好的事实论据列表显示 JSX 比普通 Dart 更好的地方。

我认为这是因为除了个人偏好之外,没有其他支持 JSX/DSX 的论据。

不是真的,之前给出了很多,只是完整地阅读了两个线程。 我之前确实提到了这两件事:
(1) 不再有“孩子”和“孩子”的东西
(2) 便于 3rd 方工具操作(解析、分析和重新生成)

使用 (2) 您可以增强标记以完成仅使用 Dart 无法完成的事情; 例如 DSX 的扩展运算符或从较小的集合中生成许多函数参数。

其他人提供了很多优点,但我不是为你挖掘它;)

(1) 如前所述,这些事情也可以在 Dart 中进行更改/改进,并且已经进行了讨论。 这在 Dart 2 发布之前不会发生。
在我看来,仅仅假设 DSX 允许所有类型的新功能而 Dart 不允许,这并不是一个公平的论点。
(2) 我很确定这也可以用 Dart 完成,当然已经有一个 Dart 解析器。

其他人提供了很多优点,但我不是为你挖掘它;)

没有必要为挖掘它们,但这种情况经常出现,你也许可以让其他人相信你确实有有效的论据。
我关注了讨论,记不起好的事实论据,其他人可能也是如此。 如果你总结它们,你可以发布一个链接到下一个问题。

如前所述,我可以接受个人偏好作为有效论据,但如果您声称也有很多事实论据,那么我认为要求指出它们是有效的。

你不断地要求“有效的论点”,当它们被给出时,你将它们视为“未来的 Dart 将拥有这个”或“这不是一个有效的论点”。

事实是,现在 Dart/Flutter 在构建小部件时到处都有嘈杂的子/子,而 XML/DSX 没有。 现在,使用 DSX 消除这种儿童/儿童噪音是一个非常有效的论据。 你能接受这是一个有效的论点吗? (只是因为你说 Dart 将来会有这个,它不会使论点无效)。

这也是一个事实,解析 XML 比解析完整的 Dart 语言要简单得多,而且每种语言都有 XML 解析器,而只有 Dart 有完整的 Dart 语言解析器。 你能看出这也是一个有效的论点吗?

有很多有效的论点,它们只是对你无效,这就是我停止争论的原因。 如果人们对所说的内容感兴趣,请完整阅读 JSX 上的 2 个线程。 我没有兴趣说服你使用 DSX,你对普通的 Dart 很满意,就这样吧; 我不是。

可选 DSX 语法的参数:

1) 加入并吸引更多来自 React(Web 和原生)的开发人员
2) 将 React Native 组件移植到 Flutter 小部件中的更好体验
3) 推动小部件中子/子属性的一致性
4)代码可读性(自以为是的论点)
5) 将逻辑 li​​nting 与 dart linting 分开查看
6) 为 UI 构建工具打开一个世界
7) 为预处理器打开生态系统

DSX +1

DSX +1

本来很想写一堆赞成/反对的,但是通过阅读所有这些评论,我觉得我会一遍又一遍地重复一切。
别再这么幼稚和无知了,没有人说你会被迫使用 DSX 编写 UI,这只是一种选择(更好的选择)。
你可以用 101203103 种不同的方式编写 JS 是有原因的。

好吧,总是可以选择编写一个分析器插件来解析 DSX 并将它们转换为常规的 Dart 函数调用,这样编译器就不必做任何额外的工作。

真正的问题是分析器插件是否适用于编译器的上下文。

如果你问我,DSX 应该只能选择加入,最好是通过某种插件。 我认为将它添加到语言本身是非常不必要的,因为 Dart 的服务器端和 Web 用户必须适应这些变化,而不仅仅是 Flutter 用户。 用 Dart 编写的绝大多数代码甚至都不需要任何 XML 语法,因此对每个人强制执行它是一个糟糕的决定。

TLDR; 如果你想要 DSX 那么糟糕,编写一个分析器插件并自己将它带到 Dart 中。 互联网会爱你,你会得到成千上万的 Github 明星,你会觉得它就是 React。 双赢。

PS我什至会和你比赛

好吧,总是可以选择编写一个分析器插件来解析 DSX 并将它们转换为常规的 Dart 函数调用,这样编译器就不必做任何额外的工作。

目前在 dart 语言中没有任何方法可以在没有任何 hack 的情况下实现这一点(想想竞争条件、递归导入和其他东西)。 这需要在一切都按预期工作、热重载、静态分析等的级别上进行集成。

如果你问我,DSX 应该只能选择加入,最好是通过某种插件。 我认为将它添加到语言本身是非常不必要的,因为 Dart 的服务器端和 Web 用户必须适应这些变化,而不仅仅是 Flutter 用户。 用 Dart 编写的绝大多数代码甚至都不需要任何 XML 语法,因此对每个人强制执行它是一个糟糕的决定。

如果您阅读该主题,那从第一天起就是这个想法。 我们只需要颤振/飞镖的支持来制作一个转译器。

TLDR; 如果你想要 DSX 那么糟糕,编写一个分析器插件并自己将它带到 Dart 中。 互联网会爱你,你会得到成千上万的 Github 明星,你会觉得它就是 React。 双赢。

阅读线程,这已经由@cbazza完成(分析器插件不会削减它)

https://github.com/flutter/flutter/issues/11609#issuecomment -388484681

PS我什至会和你比赛

伟大的! 即使是关于这将如何运作的理论也会很有趣。

SGTM。 猜猜我们都在等待某种预处理支持,那么。

我更喜欢构建器语法而不是通过构造函数传递参数

<strong i="6">@override</strong>
Widget build(BuildContext context) {
    return container()
      .height(56.0)
      .padding(8.0)
      .decoration(BoxDecoration(color: Colors.blue[500]))
      .child(text("Hello world!")
                   .style(...)
                  .build());
}

就像在https://fblitho.com/

Text.create(context)
    .text("Hello World")
    .textSizeDip(50)
    .build();

DSX +1

我得到了 JSX 的论据,但我认为有同样多的人(包括自己在内)讨厌将 XML 干扰到编程语言中的想法。 只是感觉不对(但我完全明白其他人不会有同样的感觉)。

鉴于一旦实施就几乎不可能取消功能,我建议采用预防原则。 在对 Flutter 应用程序的构建方式进行重大更改之前,让我们看看一些较新的 Dart 2 语法功能是如何发挥作用的。

@wstrange
我能理解你。 我曾经反对 JSX 并且将 js 与 xml/html 混合......然后我尝试了它。 在用了几个月的 react 之后,我爱上了 JSX。 两个杀手级优势是:

  1. 没有新的语法和实用程序
  2. 不再传递变量、函数等。

@wstrange

鉴于一旦实施就几乎不可能取消功能,

这不是给定的,谁会想到 Google 会从 Chrome 中删除 MathML?

在对 Flutter 应用程序的构建方式进行重大更改之前,让我们看看一些较新的 Dart 2 语法功能是如何发挥作用的。

这根本没有改变 Flutter 应用程序的构建方式,它只是一种不改变当前方式的替代方式,最重要的是它只是类库的不同语法。 一个简单的转译器在不需要任何来自 Flutter 类的信息的情况下进行映射,因此它适用于任何人的代码,以及现在和将来的 Flutter。

@贝索诺夫

是的,直到你花了几个月的时间使用它,然后你才意识到 React 是一个用于处理组件层次结构的库,你才会了解它。

@cbazza我可以对 Flutter 说同样的话。 花几个星期使用它,你就不会错过 JSX。

反应告诉我们一切。

截至目前, +1几乎是-1的两倍

@escamoteur
是的,这是非常公平的说法,但我在 Flutter 上花了很多时间,我当然可以看到 DSX 会增加它的价值。 正如@leedstyh所注意到的,DSX 的粉丝几乎以 2 比 1 领先,考虑到这个论坛中的人都是 Flutter 人,这非常了不起。

我有个问题:

当使用 DSX 语法时,我们隐含地假设嵌套的子/子是 Widget 类型。 如果我们想明确声明我们希望嵌套的子/子是 Widget 的特定子类型怎么办?

例如,当我希望我的自定义小部件的孩子只接受一个容器列表时,我可以用List<Container>注释孩子,一旦我放置任何与容器不同的东西,IDE 就会给出错误。 据我所知,在使用 dsx 时没有办法像这样强制执行类型安全。 也许我们在应用程序编译时可能会出现一些错误,但我认为当我打字时出现错误仍然是一种更好的体验。

我认为我们应该给每个人一些时间来尝试和熟悉 Flutter 声明 UI 的方式,至少在 v1 发布之后。 然后我们可以更好地了解这个功能。

@sandangel

很好抓!!! 我把我的虚拟帽子送给你。 我最初的原型从一开始就有一些我知道的漏洞,只是在等待人们找到它们并挺身而出。 我只是希望人们有兴趣讨论这项技术,而不是为它争吵。

我对此的解决方案是提供数组类型作为命名空间上的另一个参数。 随着命名空间越来越大,我们可以将 'children' 的缩写形式设置为 '*'。

https://spark-heroku-dsx.herokuapp.com/index.html的示例 2 中,如果操作是“容器”数组而不是默认的“小部件”,它看起来像以下替代方案:

        <actions:children:Container>
            <IconButton 
                icon={new Icon(Icons.search)}
                tooltip='Search'
                onPress={null}
            />
        </actions:children:Container>
        <actions:*:Container>
            <IconButton 
                icon={new Icon(Icons.search)}
                tooltip='Search'
                onPress={null}
            />
        </actions:*:Container>

@cbazza ,谢谢您的回复。

我想知道你的解决方案。 我们是否误用了w3shool-XML 命名空间中描述的 xml 命名空间?

正如它所说,命名空间主要用于解决 XML 文档中的命名冲突。

因此,当有人阅读上述 XML 时,他们可能会认为您在命名空间 'actions' 的命名空间 'children' 下声明了一个 Container 标签,而不是强制每个嵌套的子项都必须是一个 Container。 当我第一次阅读您的建议语法而不阅读上述解释时,它确实让我感到困惑。

我们能有更好的东西吗?

DSX 不是 XML,它类似于 XML,因此它不需要遵循 XML 语义,有点像 Angular 模板语言;)无论如何,我总是乐于接受更好的替代方案或建议,并希望在这里进行讨论。

来自 React-native,我首先支持类似 JSX 的实现,不喜欢嵌套对象,但我开始享受 OOP 并将一切都视为对象!

对于来自 React-native 的人,我强烈推荐这个插件! https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer

@clarktank
你能用 react-native(JSX)、Flutter(OOP) 和你从一个到另一个的旅程扩展你的 exp 吗?

@cbazza我认为角度模板语法确实遵循xml语义,并且我知道角度语法和xml文档之间没有冲突用例。

在 typescript 中,我们支持通用组件
所以我认为我们可以有这样的东西:

<children<Container>>
  <Container/>
</children>

但同样,通用组件用于对属性输入进行类型检查。 我不知道上述语法在这个用例中是否具有正确的语义含义。

我真的觉得 Flutter 团队专门为声明 UI 的新方法创建了当前的 API,他们认为这比 JSX 更好,我们试图将 JSX 语法绑定到当前 API 的任何努力只会让它看起来不自然/使用起来不舒服。

反应告诉我们一切。

与现在一样,+1 几乎是 -1 的两倍

这并不意味着什么。

除了那些正在观看所有 Flutter 问题的人之外,由于他们已经习惯了 JSX(并且正在明确地寻找它),所以他们在这个问题上的两倍。 因此,这意味着_想要类似 JSX 体验的人将观看所有投票 -1 的人增加一倍_。 (恕我直言,部分投票 +1 的人甚至没有真正尝试过颤振)

@sandangel

我认为角度模板语法确实遵循 xml 语义,并且我知道角度语法和 xml 文档之间没有冲突用例。

当然可以,但是 JSX 不使用命名空间,所以它不是一个感兴趣的 XML 特性。

<children<Container>>
  <Container/>
</children>

由于您将 'children' 拆分为它自己的标签,这让我想起了 React 的新 Fragment 标签。 这是肯定的冗长和简洁之间的平衡。

我真的觉得 Flutter 团队专门为声明 UI 的新方法创建了当前的 API,他们认为这比 JSX 更好,我们试图将 JSX 语法绑定到当前 API 的任何努力只会让它看起来不自然/使用起来不舒服。

Flutter 在代码中声明 UI 的方式并没有什么新东西,也许使用 DSX 对您来说是不自然/不舒服的,但对 JSX 开发人员来说却不是。 JSX/DSX 非常适合 Flutter,它像手套一样合身,如果您不喜欢手套,请赤手空拳;)

@a14n ,

这并不意味着什么。

确实如此! 你可以用“感觉”、“思考”、“怀疑”、“恕我直言”、“意见”来争论,但这是数据,一个具体的数据点。 如果数据无用,则不应收集。 我猜数据是无用的,因为它不会描绘你的画面。

@cbazza我的意思是,当我们试图回答我上面关于为孩子/孩子强制执行小部件子类型的问题时,我觉得 Dart 代码比 JSX 做得更好。

DSX 不是 XML,它类似于 XML,因此不需要遵循 XML 语义

当然可以,但是 JSX 不使用命名空间,所以它不是一个感兴趣的 XML 特性。

我不确定,但我已经阅读了您上面的一些评论,并且我认为您已经交替提到了 JSX/XML 节点。 无论如何,我个人认为使用命名空间作为解决方案并不理想。

只是比较

<actions:children:Container>

</actions:children:Container>

actions: <Container>[]

句法。

@sandangel

是的,对于这种情况,标记语法更加冗长,这就是为什么我提到孩子的缩写形式是“*”。 无论如何,这种情况是例外而不是规则。 大多数时候你甚至不需要指定“孩子”,更不用说“容器”了; 但是功能需要在那里覆盖所有可能的用例。

@a14n投票就是投票,这肯定意味着。

我尊重你的感受,也许这是真的。 但即使采用反向比率(1 比 2),这仍然意味着 33% 的用户群。 你能说33%是一小部分吗?

想要类似 JSX 体验的人

是的,有人在看。 这也意味着_缺乏类似 JSX 是阻止人们选择 Flutter 的原因之一_。

Flutter 面向更多的开发者,不仅仅是那些阅读所有问题的人。

@jstansbe
我是一名自学成才的程序员,和大多数自学成才的人一样,我是从 Javascript 开始的。
然后我开始学习 React 和 React-Native。 我认为近年来,特别是在 ES6 之后,OOP 风格被添加到了 Javascript 中。

所以像我这样的人不习惯 OOP 风格的编程。 尽管 React 原生Component是类,就像 Flutter 中的Widgets一样。

JSX 有点隐藏纯 OOP 图片。 基本上,它隐藏了引擎盖下发生的事情。 注意:React 是为 Web 开发人员设计的,Web 开发人员习惯于 html 语法。 这就是为什么 JSX 在 Web 开发人员中如此受欢迎的原因。

就个人而言,我认为纯 OOP 对于大型项目更有意义。

@克拉克坦克

在讨论计算机语言时,您必须注意:
(1) 句法——构成语言的字符和单词
(2) 语义——那些字符和单词的含义

例如,许多语言中的函数调用如下所示(即具有以下语法):

a = someFunction(param1, param2)

现在想象一下,另一种语言决定在函数调用中使用方括号而不是圆括号; 它如下所示:

a = someFunction[param1, param2]

这里的问题是语法不同但语义相同。 我的意思是两者基本上都在进行函数调用,但语法不同。

JSX 有点隐藏纯 OOP 图片。 基本上,它隐藏了引擎盖下发生的事情。

一点也不真实。 JSX/DSX 只是完全相同的事物的不同语法(语义相同)。 对于 JSX,XML 标签只是创建 React 组件(就像你可以在纯 Javascript 中做的那样)。 在 DSX 的情况下,XML 标签只是创建 Flutter Widgets(就像您可以在 Pure Dart 中那样)。 语法不同,但它生成完全相同的东西,所以它在引擎盖下是相同的。

注意:React 是为 Web 开发人员设计的,Web 开发人员习惯于 html 语法。 这就是为什么 JSX 在 Web 开发人员中如此受欢迎的原因。

JSX 很受欢迎,因为它是管理组件树层次结构的好方法,无论是用于 Web、移动设备还是任何 UI 开发。 请注意,在下面的代码中,您不知道下拉组件是用于 Web 还是移动设备。

https://facebook.github.io/jsx/

// Using JSX to express UI components.
var dropdown =
  <Dropdown>
    A dropdown list
    <Menu>
      <MenuItem>Do Something</MenuItem>
      <MenuItem>Do Something Fun!</MenuItem>
      <MenuItem>Do Something Else</MenuItem>
    </Menu>
  </Dropdown>;

render(dropdown);

就个人而言,我认为纯 OOP 对于大型项目更有意义。

那个怎么样? (考虑到使用 JSX/DSX 或 Pure Javascript/Dart 在后台生成完全相同的东西)。

@cbazza

我使用 react-native 快一年了,不知道 JSX 元素是被实例化的对象,直到我开始使用 Flutter/Dart。 从我的角度来看,它确实隐藏了 OOP 图片,尽管正如您所说,它在语义上做了同样的事情!

在大型应用程序中,JSX 也可能变得像重度嵌套对象一样丑陋。 所以在语法上,我宁愿保持一致,也不愿引入另一种可能令人困惑的风格。

@克拉克坦克

在大型应用程序中,JSX 也可能变得像重度嵌套对象一样丑陋。 所以在语法上,我宁愿保持一致,也不愿引入另一种可能令人困惑的风格。

对我来说,让它看起来与其他代码不同实际上是一个好处。

(我提前为文字墙道歉。)

作为一个没有使用 React-Native 或 Flutter 足够长的时间来认为自己是原始 Dart 或 JSX/DSX 是否“更好”的权威来源的人,这个问题线程读起来相当有趣。 不过,有几件事我想把我的 0.02 美元放在上面。

首先,我发现自己同意很多人关于 JSX 的本质以及它如何使开发人员受益的观点。 首先,JSX 被设计为一种“动态 HTML”形式,可以内联到现有的 Javascript 代码中。 对于像 React 这样的基于 JS 的 Web 平台来说,它是必不可少的,因为它使 Web 开发人员能够干净而有效地与 DOM 交互,而不必与糟糕的原生方式(或唯一稍微更好的 jQuery 方式)搏斗。 此外,就其本质而言,JSX 鼓励可以轻松与底层数据分离的 UI 开发,从而促进组织良好的项目结构。 在那种环境下,JSX 是一种提高生产力的工具,我觉得几乎不可能对此提出异议。

该段落与 React-Native 的关系是,即使它是一个移动开发平台,它也是 React 的直接后裔。 因此,几乎所有的语法和范式最初仍然是在考虑 Web 开发的情况下创建的。 这是设计使然 - RN 的全部特点是您可以“使用 React 创建跨平台移动应用程序”,因此在使用它时感觉就像是 Web 开发。 RN 应用程序也主要用 Javascript 编写,因此包含 JSX 是很自然的。 JSX 帮助 RN 开发的原因几乎与它在 Web 开发中的帮助相同。 (我真的认为这是一个很大的原因,至少在 RN 中,JSX 方法比原生方法更频繁地使用。RN 本身只是 _feels_ 像一个 web 平台,所以更自然的方法不可避免地会出现成为主导。)

而 Flutter 则没有这样的设计理念。 它旨在成为一个纯粹的原生跨平台解决方案,尽管它声明它是受 React-Native 启发的,但它编写的更像是一个原生桌面或移动应用程序,而不是一个 Web 应用程序。 它还使用 Dart 而不是 Javascript 运行,从集成 JSX 之类的角度来看,这是一个主要考虑因素。 一方面,虽然 JS DOM 函数可能非常冗长(由于函数的设计和 JS 语言本身),但作为一种语言,Dart 更便于使用干净的 UI 声明性代码,而 Flutter 在很大程度上做得很好保持 UI 构造函数简洁。 另一方面(正如@sandangel指出的那样)Dart 是一种静态类型语言,因此 JSX 的本质是为像 JS 这样的动态类型语言设计的,例如,在 UI 构造函数需要特定类型的小部件,唯一增加冗长的解决方案。 就个人而言,这感觉像是一个解决方案,随着时间的推移,将不可避免地导致 DSL 变得臃肿且难以维护,因为它必须考虑到系统中越来越多的固有用例,而这些用例并不是它的本意。用于。

因此,我真的不认为 JSX/DSX 将如何提高 Flutter 开发效率,而不仅仅是个人喜好问题。 总体而言,这两种语法在冗长方面大致相当,并且在特定情况下失去了冗长,它在清晰度上弥补了它(例如,结束 XML 标记)。 它主要归结为是否有人从面向 Web 的背景(React/RN、Angular 等)或从本机背景(Java/Kotlin/Swift、WPF/UWP 等)来到 Flutter,这将决定哪个他们更喜欢的方法。 即使仅在这个线程上,也有很多用户故事说他们一开始对 JSX 非常怀疑,但在使用了几个月后,他们的看法变成了“不能没有”。 (虽然我愤世嫉俗的部分想指出,如果他们给它一个机会,同样的事情很可能会发生在他们身上。)

说了这么多,我真的不认为自己同意 DSX 应该成为 Flutter 团队的官方支持,作为原生 UI 构造函数的替代方案。 虽然它作为第三方解决方案非常好(以及@cbazza实际实现它的所有道具),但它并不真正符合 Flutter 作为非基于 Web 技术的平台的核心性质。 因此,任何想在自己的项目中使用 DSX 的人都可以拥有更多的权力,但我会支持 Flutter 团队可以而且应该花时间在许多其他更重要的事情上的心态。

话虽如此,虽然我不太同意官方支持 DSX,但我确实认为应该有一种官方的 UI 格式_some_ 种。 正如@birkir指出的那样,几乎每个主要的原生 UI 平台,无论是桌面还是移动设备,除了直接基于代码的方法外,还有一种 UI 格式(而且它们中的大多数都被预处理为基于代码的方法)。 将 UI 文件与逻辑文件分开一直是采用 MVVM 模式的推荐方式(顺便说一句,这一直是让我对 JSX 产生误解的一件事)。 因此,我要争辩的是,Flutter 有类似的东西——而不是内联 UI DSL 格式,它应该有一个单独的 UI 格式,旨在进入它自己的文件,远离 Dart 代码。

作为这种思路的一部分,我实际上在上周末为此做了一些工作。 如果可以让我稍等片刻,我开发了一个我创造了“FLUI”的项目,这是我试图展示这种格式可能是什么样子的尝试。 我没有使用现有的 DSL(或修改版本),而是开发了一个全新的 DSL,它从 YAML 中汲取灵感,并且尽我所能保持接近 Flutter-constructor-approach 布局的“感觉”。 当然,这是一个_非常_早期的实现,所以我真的不希望它没有大量问题,但我已经包含了处理器脚本的源代码(用 C#/.NET 标准编写),以便人们可以玩如果他们愿意的话。 :)

作为 React/RN 和 Flutter 用户,我非常不同意“DSX”的想法。

DSX 不会带来任何东西。 JSX 用于反应,因为 JS 语法很糟糕。 但是在 Flutter 的情况下,小部件的创建非常容易。

经典:

Widget build(BuildContext context) {
  return Center(
    child: Text("foo"),
  );
}

它已经开箱即用,可读,易于编写,类型/泛型兼容,并且没有任何不必要的重复。

对于当前语法,您可能会遇到的唯一抱怨是“很难知道小部件的右括号在哪里”

不过话说回来,官方支持的 IDE 的 dart 插件解决了这个问题。 所以当我们在 vscode 中打开之前的代码时,我们会看到

Widget build(BuildContext context) {
  return Center(
    child: Text("foo"),
  ); // Center
}

至于“很难区分休闲代码和 UI 代码”,react 规则也适用于颤振:

小部件应该是愚蠢的或聪明的。 智能小部件没有 UI 逻辑。 愚蠢的小部件只有 UI 逻辑。

如果您遵循这种模式,您将永远不会陷入无法将 UI 与其他 UI 区分开来的情况。
在遵循 BLoC 模式时更是如此; 这会严格执行业务和 UI 的分离。

JSX 用于反应,因为 JS 语法很糟糕

非常自以为是的陈述,根本不正确。


render() {
  return React.createElement(Container, { padding: EdgeInsets.all(20.0) },
    React.createElement(Text, { style: { color: Colors.black } },
      'foo'
    )
  );
}
Widget build(BuildContext context) {
  return Container(
    padding: EdgeInsets.all(20.0),
    child: Text(
      'foo',
      style: TextStyle(color: Colors.black)
    ),
  );
}

render() {
  return (
    <Container padding={EdgeInsets.all(20.0)}>
      <Text style={{ color: Colors.black }}>foo</Text>
    </Container>
  );
}
Widget build(BuildContext context) {
  return (
    <Container padding={EdgeInsets.all(20.0)}>
      <Text style={TextStyle(color: Colors.black)}>{'foo'}</Text>
    </Container>
  );
}

非常自以为是的陈述,根本不正确。

默认反应语法中有很多不需要的字符。
让我们比较每种语法的单词重复和字符数(不包括函数定义、缩进和“返回”)

没有 JSX 的反应:

  • 133 个字符,包括 3 个括号、3 个括号、3 个: 、4 个,和 11 个空格
  • React.createElement写了两次

JSX:

  • 104 个字符,带 2 个括号,3 个括号,1 个: ,4 个<>和 5 个空格
  • ContainerText写了两次

镖:

  • 99 个字符,带 2 个括号,4 个: ,3 个,和 4 个空格
  • 无重复

就字符而言,这里明显的赢家是飞镖语法。


现在我们还必须考虑其他飞镖细节。

Dart 类型为单子与多子,具有const构造函数,并允许泛型甚至定位参数。 JSX 不支持这些。

一些会严重转换为 JSX 的示例:

并非总是children

Scaffold(
  appBar: AppBar(),
  body: Container(),
)

OR

SingleChildScrollView(
  child: Container(
    height: 100.0,
  ),
)

const小部件本身的构造函数

const Padding(
  padding: const EdgeInsets.all(4.0),
)

仿制药

NotificationListener<ScrollNotification>(
  onNotification: (foo) {

  },
  child: child,
)

定位道具:

Text("foo")

命名构造函数

Positioned.fill(
  child: Container(),
);

builders(dart 不支持联合类型,所以children不能同时是 Widget 和函数)

Builder(
  builder: (context) => Container(),
)

@rrousselGit

正如之前多次提到的,DSX 只是一个不同的
语法,它是 Dart 的超集,所以你可以做的一切
Dart 你可以在 DSX 中完成。 你也可以混合搭配
您认为合适的语法。 显然你甚至都懒得去检查
了解哪些 DSX 功能是为了支持
镖:
https://spark-heroku-dsx.herokuapp.com/index.html

-1----------------------------------------
在飞镖中:

Scaffold(
  appBar: AppBar(),
  body: Container(),
)

OR

SingleChildScrollView(
  child: Container(
    height: 100.0,
  ),
)

在 DSX 中:

<Scaffold
  appBar={<AppBar/>}
  body={<Container/>}
/>

OR

<SingleChildScrollView>
  <Container
    height={100.0}
  />
</SingleChildScrollView>

-2----------------------------------------
在飞镖中:

const Padding(
  padding: const EdgeInsets.all(4.0),
)

在 DSX 中:

const Padding(
  padding: const EdgeInsets.all(4.0),
)

-3----------------------------------------
在飞镖中:

NotificationListener<ScrollNotification>(
  onNotification: (foo) {

  },
  child: child,
)

在 DSX 中:

<NotificationListener<ScrollNotification>
  onNotification={(foo) {

  }}
  child={child}
/>

-4----------------------------------------
在飞镖中:

Text("foo")

在 DSX 中:

<Text ["foo"]/>

-5----------------------------------------
在飞镖中:

Positioned.fill(
  child: Container(),
);

在 DSX 中:

<Positioned.fill>
  <Container/>
</Positioned.fill>

-6----------------------------------------------------
在飞镖中:

Builder(
  builder: (context) => Container(),
)

在 DSX 中:

<Builder
  builder={(context) => <Container/>}
/>

但是从反应到颤动更容易转换的论点是无效的。 由于 JSX 与您的原型完全不同:

<MyAppBar>
    <title:Text [] style={Theme.of(context).primaryTextTheme.title}>
        Example title
    </title:Text>
</MyAppBar>

您在此处或链接中的所有示例都没有真正简化代码或提高可读性

尽我所能与您对缺少 JSX 的感觉(开始颤振时得到相同的感觉)联系起来,经过一些经验,本机语法实际上感觉还不错


作为旁注,对于您的关注点分离,有一个更好的解决方案。 那是一个模板文件
您可以在小部件旁边放置一个 xml/yaml 文件。 然后使用 dart 提供的很棒的代码生成工具。

我宁愿选择一个:

// main.dart
import 'package:flutter/material.dart';

part 'main.g.dart';

class MyState extends StatefulWidget {
  <strong i="14">@override</strong>
  _MyStateState createState() => _MyStateState();
}

class _MyStateState extends State<MyState> {
  <strong i="15">@override</strong>
  Widget build(BuildContext context) {
    return $myStateStateTemplate(theme: Theme.of(context));
  }
}

结合一个

// main.xml
<strong i="19">@theme</strong> ThemeData

<Container  color={@theme.cardColor} />

然后使用自定义代码生成生成以下 dart 文件:

part of 'main.dart';

Widget $myStateStateTemplate({ThemeData theme}) {
  return Container(
    color: theme.cardColor,
  );
}

最终结果甚至比用于分离 UI/逻辑的“DSX”更好。 这对潜在的 UI 生成器也更好。 使用built实现起来要容易得多。

由于 JSX 与您的原型完全不同:

真的 !!! 这些讨论中唯一激进的是反对者的反应。

正如这张票的标题中所述,DSX 类似于 JSX,它不是 JSX 相同的,否则它会被称为 JSX; 并且对它的添加是次要的,并为开发人员提供了选择。

你可以这样写:

<MyAppBar>
    <title:Text [] style={Theme.of(context).primaryTextTheme.title}>
        Example title
    </title:Text>
</MyAppBar>

or

<MyAppBar>
    <title:Text ['Example title'] style={Theme.of(context).primaryTextTheme.title}/>
</MyAppBar>

or

<MyAppBar
    title={<Text [] style={Theme.of(context).primaryTextTheme.title}>
        Example title
    <Text>}
/>

or

<MyAppBar
    title={<Text ['Example title'] style={Theme.of(context).primaryTextTheme.title}/>}
/>

嗯,您似乎将“关注点分离”与“技术分离”混淆了。 这些事情是非常不同的; 您将 dart 代码和标记代码分隔在不同的文件中,只是“技术分离”,并没有提供“关注点分离”的任何好处。 这里的一个问题是干净地封装可重用代码的组件/小部件,在该组件/小部件内部使用不同的技术并不重要。

同样,您推荐的分离技术也远不如 JSX/DSX,后者将宿主语言用于所有命令式构造(for 循环、函数调用、if 语句等)。

在此处(尤其是)发布了大量代码和示例之后,我得出结论,与 DSX 和 Dart 相比,JSX 为 JS 增加了更多价值。 但是从我的角度来看,一个功能非常重要:关闭标签。 喜欢:

<SingleChildScrollView>
  <Container
    height={100.0}
  />
</SingleChildScrollView>

此处相比,减少了很多深层结构中的认知复杂性:

SingleChildScrollView(
  child: Container(
    height: 100.0,
  ),
)

但是,如果你像这样使用它:

<Scaffold
  appBar={<AppBar/>}
  body={<Container/>}
/>

有一点点利润。

正如这张票的标题中所述,DSX 类似于 JSX,它与 JSX 不同

你错过了我的“但是从反应到颤动更容易转换的论点是无效的。”

DSX 的一半争论是“JSX 在 React 中很流行,我们在这里也需要这个”。 但是你提出了一些与 JSX 不同(而且更复杂)的东西。
另一半是关于将 UI 与代码分离; 模板文件也可以做到这一点。

同样,您推荐的分离技术也远不如 JSX/DSX,后者将宿主语言用于所有命令式构造(for 循环、函数调用、if 语句等)。

不对。 你可以在你的模板文件中做if和东西。 查看cshtml或角度模板。

这个东西是一个模板文件,只要你已经有一个解析器,就可以在不到一周的时间内为 Flutter 实现完全工作。
无论是 yaml、xml、cshtml 还是带有指令的 html。

虽然 DSX 需要大量工作。


@Bessonov他们最近在支持的 IDE 上添加了虚拟评论来模拟结束标记。

因此,在您的 vscode 中,您将看到以下内容:

SingleChildScrollView(
  child: Container(
    height: 100.0,
  ), // Container
) // SingleChildScrollView

关闭标签的好处。 无需键入它们

@rrousselGit

他们最近在支持的 IDE 上添加了虚拟评论来模拟结束标记。

是的,我在引用的评论中看到了这一点。 但不一样。 这引入了对齐移位和干扰阅读流程。 这在其他 IDE 和文本处理器中对我没有帮助。

东西是一个模板文件

恕我直言模板患有 NIH 综合症。 我并不是说混合 PHP 和 HTML 的方法是正确的方法。 但是 React 用 JSX 展示了它是如何做得更好的。

@rrousselGit

你错过了我的“但是从反应到颤动更容易转换的论点是无效的。”

不,我完全没有错过评论,你告诉我来自 JSX 的人会觉得 DSX 太复杂是没有意义的。

DSX 的一半论点...

选择 DSX 的原因有很多,但无论出于何种原因,人们都会选择他们喜欢的东西。

不对。 您可以在模板文件中执行 if 和 stuff。 查看 cshtml 或 Angular 模板。

这个东西是一个模板文件,只要你已经有一个解析器,就可以在不到一周的时间内为 Flutter 实现完全工作。
无论是 yaml、xml、cshtml 还是带有指令的 html。

虽然 DSX 需要大量工作。

完全相反,DSX 只实现了 2 个 xml 转换,并从托管语言中免费获得了其他一切。 想象一下尝试在您的新模板语言中重新实现 Dart 的强大功能的努力。 不用了,我要飞镖。

不,我完全没有错过评论,你告诉我来自 JSX 的人会觉得 DSX 太复杂是没有意义的。

同样的事情也适用于当前的 dart 实现。


无论如何,我认为我们不能在这里互相说服。 因此,我将列出更多的原因,说明为什么我不喜欢 JSX 在 Flutter 中,然后“等等看”。

1. Widget 创建与 React 不同

在 react 中,它是处理组件创建的库。 JSX 很好,因为它说“不要担心事情是如何运作的。我们为你做事”。

在颤振中,情况并非如此。 我们在每次构建调用时手动实例化一个新的小部件。 理解这一点非常重要,而 JSX 会让它变得不那么清楚。

并且,在该逻辑的延续中:

2. 人们可能认为<Foo />做了一些new Foo()没有做的特别的事情

<Foo />的方法感觉很特别。 似乎它在框架中内置了一些无关紧要的东西。 这在反应中是正确的,其中组件被包装在React.Element中。
这会将反应转化为<Foo /> != new Foo()并且不能直接访问Foo

这不适用于颤振,可能会导致混乱。

还 :

<Foo>
  <Bar />
</Foo>

在反应中,如果Foo从不使用它的孩子,那么Bar永远不会被实例化。 Foorender方法返回后被实例化。
在颤振中,情况正好相反。 BarFoo都会立即创建

这可能会导致 React 开发人员制作未经优化的颤振代码。

3. 一般来说 Dart/flutter 不是 JS/react

如果我们在 dart 中添加 JSX,我已经可以看到关于类型联合的问题或者能够做到
return foo && <Component />或即将到来的异步渲染反应。
理由是“我们已经有了 JSX,所以我们也可以拥有它!”

为了不必在 dart 中实现最新的 JSX/react 功能,我更喜欢专有语法或根本没有语法

4. JSX 使一些飞镖细节不清楚

一个小例子, Scaffold需要appbarPrefferedSizeWidget
如果我们使用 JSX 创建Scaffold ,人们会期望您可以用另一个 JSX 替换任何给定的 JSX。 这不是真的

我的意思是,这让我们很不清楚为什么我们可以这样做

<Scaffold
  appbar={<AppBar />}
/>

但不是

<Scaffold
  appbar={<Container />}
/>

@rrousselGit

无论如何,我认为我们不能在这里互相说服。 因此,我将列出更多的原因,说明为什么我不喜欢 JSX 在 Flutter 中,然后“等等看”。

我不同意你说的很多话,但我感谢你的努力,因为你花时间深入思考这个问题。

  1. Widget 创建与 React 不同

对我来说这并不重要,因为这只是一个实现细节,从概念上讲,一旦你看到一些 XML,在 React 中它是一个组件,在 Flutter 中它是一个小部件。

  1. 人们可能认为做了一些 new Foo() 没有做的特别的事情

我认为人们很快就会知道 Dart/DSX 不是 Javascript/JSX。

  1. 一般来说 Dart/flutter 不是 JS/react

是的,我们最终在某件事上达成了一致,但即使它们不同,共同点是它们是声明性 UI 框架,我认为声明性树结构可以很好地使用 JSX/DSX 处理。 它使您保持声明式编程的思维方式。

如果我们在 dart 中添加 JSX,我已经可以看到关于类型联合的问题,或者能够在 react 中进行return foo && <Component />或即将到来的异步渲染。
理由是“我们已经有了 JSX,所以我们也可以拥有它!”

我们没有在 Dart 中添加 JSX,我们正在添加 DSX,它与 JSX 不同但有相似之处,而且熟悉度是一件大事。

为了不必在 dart 中实现最新的 JSX/react 功能,我更喜欢专有语法或根本没有语法。

所以有了这个推理,你为什么要使用 Dart? 它看起来与 Java 非常相似,但又与 Java 不同; 见鬼,让我们放弃所有这些 Java 关键字和概念,并想出一些与 Erland 模糊相似的东西,你只能用一只手编程,同时在珠穆朗玛峰顶部做椒盐卷饼瑜伽;)

  1. JSX 使一些飞镖细节不清楚

不是真的,如果你连接无与伦比的小部件,Dart 编译器会吐出错误消息,就像你在普通 Dart 中那样。 我不能足够强调 DSX 只是简单的语法糖,没有魔法,只是同一事物的不同语法。

@cbazza我花了几个小时阅读您的帖子,非常感谢您在这个问题上所做的努力。 但我认为结束争论很容易。 还记得 Flux 是 react 的官方状态管理解决方案,但现在每个人都在使用 redux 吗? react-native 有多少导航库? 只需创建一个 DSX 存储库,然后让 react 开发人员参与进来。

@rrousselGit

我以前从未在 Dart 中见过part / part of语法,而且我很难找到任何文档。 它是 Dart/Flutter 官方支持的吗? 我很想在 FLUI 中使用类似的东西。


@cbazza

你一直在用 DSX 的理由兜圈子。 DSX 不是 JSX。 DSX 类似于 JSX。 DSX 旨在成为 React 开发人员熟悉的语法。 DSX 只是 Dart 的语法糖。 人们会知道 DSX 不是 JSX。 (等等。)

虽然我明白你试图用所有这些解释来表达的观点,但我认为你必须继续做出这些解释的事实揭示了一个关于 DSX 本质的主要问题,这也是rrouselGit提出的一点。 即使您一直说 DSX _不是_ JSX,发现它的人也会认为它是,这是一个问题。 JSX 和使用它的人来自一个在概念上与 Dart/Flutter 根本不同的生态系统。 因此,为“熟悉”而开发功能不一定是好事。 正如所指出的那样,其中一个更明显的原因是,人们将尝试这样的事情:

Widget build(BuildContext context) {
    return isDialogVisible && <Widget>...</Widget>;
}

因为它们来自 Javascript/JSX,所以他们希望该语法在 DSX 中工作。 如果不这样做,它就会成为认知失调的一个点,这实际上可能会_伤害_他们不仅对 DSX,而且对整个 Flutter 的兴趣。 当熟悉被用作一种让人们轻松进入新事物的手段时,它是有益的,但这可能是一把双刃剑——当 90% 的特征相同时,剩下的 10% 只会让人感到沮丧和烦恼。

DSX 的另一个问题是,无论它是第三方插件还是被 Flutter 正式采用,它都不太可能很快成为无缝集成的功能。 正如您自己所说,要真正与 Flutter 调试和部署过程配合使用,不仅需要 Flutter 团队的官方支持,还需要 Dart 团队的官方支持。 如果做不到这一点,没有预处理和工具支持,DSX 工作的唯一方法是使用外部手动转换工具,这只是开发人员必须经历的另一个(可能很长)步骤。


在打字时,我想到了另一件事。 在这个帖子中有几个支持 JSX 的人称赞 JSX,说 UI 设计的“关注点分离”方法确实是他们考虑再次开发 UI 的唯一方法。 如果是这样的话,为什么 React 是唯一一个在市场上使用它的框架呢? 本机和跨平台移动应用程序框架都坚持使用它们的故事板、XML 文件、XAML 文件和其他此类 UI 定义 DST。 即使是其他流行的 JS 框架,如 Angular 和崭露头角的 Vue,仍然采用“技术分离”的方法。 React 开发人员说 JSX 是未来的发展方向,但我还没有看到它出现在 React 之外的任何地方,并出现在一个真正受到关注的框架中。

@andrewackerman

part / part of是现有的飞镖功能。 它以某种方式将两个文件合二为一。 通常用于代码生成。

有一些使用这种技术的真实案例场景。 就像json_serializable它根据类的属性生成一个toJSON方法和一个fromJSON工厂。

part / part of自己并没有真正做任何事情。 有趣的部分是当你将它结合到类似source_gen的东西时。

@sunnylqm

我不认为将代码放在 repo 上会解决我的问题,因为当前的问题是关于正确地将 DSX 与 Flutter 工具集成,以便为 .dsx 文件上的调试器、自动完成等提供出色的开发人员体验。

告诉用户他们可以使用 DSX 但不能使用调试器或享受自动完成功能对我来说是行不通的。 如果有人想提供帮助,我需要想办法为 Dart 工具和 VS Code Dart 插件添加完整的预处理支持(带有源映射)。一旦工具支持 DSX 或任何其他转译语言(任何语言是 Dart 的超集,但将所有内容都编译为 Dart)就可以了。

@andrewackerman

我不需要证明任何事情,我非常有信心 DSX 会大受欢迎,仅这张票就有近 100 人对它感兴趣。

如果做不到这一点,没有预处理和工具支持,DSX 工作的唯一方法是使用外部手动转换工具,这只是开发人员必须经历的另一个(可能很长)步骤。

DSX 转译器速度非常快,可以将 .dsx 文件转换为 .dart 文件的速度比眨眼还快,因此速度不是问题; 只是试图获得功能对等,以使其成为人们使用 DSX 的明智之举。

如果是这样的话,为什么 React 是唯一一个在市场上使用它的框架呢? 本机和跨平台移动应用程序框架都坚持使用它们的故事板、XML 文件、XAML 文件和其他此类 UI 定义 DST。

只需制作一个时间表,您就会看到 UI 开发的演变。 Android 和 iOS 以目前的方式进行开发始于 10 多年前,因此它使用了 10 年前的技术(完全命令式技术)。 大约 8 年前,响应式 UI 开发(声明式)技术开始出现在 Web 上。 React 出现在 5 年前,它是第一个将技术与 JSX 无缝结合的 Reactive 框架。 Vue 现在是最新的响应式框架,它支持旧的“技术分离”技术,但它也支持 JSX。 在移动端 Flutter 是最新的,它使用 Reactive 框架技术作为 React,它可以利用 DSX,就像 Vue 利用 JSX 一样。 Vue 正在扼杀 Angular,因为它为开发人员提供了选择,而不是过于固执己见。

单独模板文件的问题在于,与用于业务逻辑的编程语言相比,那里的命令式编程结构(if、for 循环等)非常弱。 对我来说,以 JSX 的方式结合 2 显然是未来。

React 开发人员说 JSX 是未来的方式,

它是 !!!

但我还没有看到它出现在 React 之外的任何地方,它已经获得了任何真正的吸引力。

Vue 使用 JSX

@cbazza

我不需要证明任何事情,我非常有信心 DSX 会大受欢迎,仅这张票就有近 100 人对它感兴趣。

我不是说你_do_需要证明任何事情。 当你坚持让 Flutter 团队接受这个提议并自己实施时,是的,我会说你有相当多的理由要做。 既然你正在尝试自己做,你可以做任何你想做的事,只要你认为有足够的理由,对你有更多的权力。 我只是在说明我认为它可能不像你想象的那么容易或受欢迎的原因,我把球放在你的球场上是为了对抗他们。

DSX 转译器速度非常快,可以将 .dsx 文件转换为 .dart 文件的速度比眨眼还快,因此速度不是问题; 只是试图获得功能对等,以使其成为人们使用 DSX 的明智之举。

我假设,到目前为止,您已经在尺寸微不足道的 UI 和应用程序上对其进行了测试。 那些不平凡的呢? 那些属于边缘情况的呢? 此外,该过程所花费的实际时间并不是唯一相关的部分——开发人员在构建之前必须通过另一个手动操作清单这一事实足以让许多人感到厌烦。

你还没有真正发布项目的源代码,所以没有人能够完成你的过程,仔细检查你的发现,并提出改进建议。 在这一点上,任何人真正能做的就是相信它既方便又高效。

Vue 使用 JSX

我已经使用 Vue 快一年了,在那段时间里,我浏览了大量的开源项目 repos,看看不同的事情是如何完成的。 虽然我不认为自己是 Vue 大师,但我要说的是,我从未在其中任何一个人中看到 JSX 实际使用过——人们似乎非常喜欢.vue方法(模板-script-styling) 优于 render+JSX 方法。 我什至不知道 Vue 甚至支持 JSX(至少通过 babel 插件),直到在您回复后我对 Vue 文档进行了一些挖掘,并在渲染函数部分发现了一小段信息。

但这与我的整体观点无关。 Vue 仍然是一个 Javascript 框架。 Flutter 肯定不是。 因此,有很多原因使 JSX 在以 Javascript 为中心的环境中成为最新最伟大的东西,不会转化为 Dart+Flutter,其中许多已经在本线程中介绍过。

它是 !!!

在我看到它在非 Javascript 开发环境中流行之前,我会恭敬地不同意。

Vue 使用 JSX

Vue 指定具有广泛的用途。 JSX 就在“那里”。 但这不是主要的语法
如果您愿意,可以将 JSX 插入 Angular。 虽然没有人这样做

React 开发人员说 JSX 是未来的方式,
它是 !!!

未来的一个重要候选者是网络组件。 它们直接在 html 中使用,类似于您在 Angular 或最常见的 Vue 形式中找到的内容

@andrewackerman

开发人员必须通过另一个手动操作清单才能构建,这一事实足以让许多人感到厌烦。

谁说过手动操作? 我不是清楚地表明我正在尝试获得完整的无缝 IDE 集成(为开发人员提供最佳的用户体验)。

你还没有真正发布项目的源代码,所以没有人能够完成你的过程,仔细检查你的发现,并提出改进建议。

这与使用 DSX 的人有什么关系? 我使用 JSX 已经 2 年多了,对它的源代码毫不在意。 是否需要查看 Dart 编译器的源代码才能在 Dart 中编程?

我要说的是,我从未见过实际使用过 JSX ——人们似乎更喜欢 .vue 方法(模板脚本样式)而不是 render+JSX 方法。

JSX 是一个新增功能,因此传播需要时间,但重要的一点是 Vue 接受其他方法,而不强迫开发人员使用应该在 Vue 中完成事情的“正确方法和唯一方法”。

Vue 仍然是一个 Javascript 框架。 Flutter 肯定不是。

Riiiiight,所以你使用 DSX 和 Flutter 来代替 JSX。

@rrousselGit

未来的一个重要候选者是网络组件。

Web 组件是动物,死了但仍在行走; 它们与加拿大的袋鼠一样普遍。 我可以继续几天,但为了避免离题......
https://dmitriid.com/blog/2017/03/the-broken-promise-of-web-components/

@cbazza

谁说过手动操作? 我不是清楚地表明我正在尝试获得完整的无缝 IDE 集成(为开发人员提供最佳的用户体验)。

你还说你需要 Flutter/Dart 团队的预处理支持才能做到这一点。 我不正确吗?

这与使用 DSX 的人有什么关系? 我使用 JSX 已经 2 年多了,对它的源代码毫不在意。

JSX 是由 Facebook 为 React 开发的,经过严格的提案/设计/实施/迭代过程,然后在您接触它之前几年就发布到世界各地。 它已经在现实世界环境中一次又一次地经过严格测试和验证。 这是一项成熟的技术。 没有理由要求查看此类产品的规格表。

另一方面,DSX 今天是由您和少数人开发的。 您已经雄辩地谈论了它可以做什么以及将能够做什么,但我们实际上_看到的只是一小部分专门构建的代码片段以及您所说的它们是由转译器生成的。 甚至想要尝试并提出可能的更改或改进建议的人都无法这样做,因此他们没有理由支持您在“Yay JSX!”之外的努力。

我不是在指责你撒谎或其他任何事情,我只是说 JSX 已经赢得了 DSX 没有的信心,所以如果你不让人们修补它,你怎么能转过头来呢?

JSX 是一个新增功能,因此传播需要时间,但重要的一点是 Vue 接受其他方法,而不强迫开发人员使用应该在 Vue 中完成事情的“正确方法和唯一方法”。

JSX 已经在 Vue 中使用了将近 2 年了。 而且与 Vue 本身不同,JSX 是一种无需介绍的预先存在的技术,尤其是对于熟悉 React 的人来说。 如果 JSX 要席卷 Vue.js 世界,我不禁觉得它现在已经做到了。 (特别是如果有任何迹象表明像你声称的那样有很多人在 Flutter 中叫嚣着使用 JSX。)

Riiiiight,所以你使用 DSX 和 Flutter 来代替 JSX。

JSX 和 DSX 是同一个语法概念。 问题在于,JSX 是建立在像 JavaScript 这样的弱类型动态语言上的,而 DSX 是建立在像 Dart 这样的强类型静态语言上的。 这意味着 DSX 必须解决很多问题,如果 JSX 不是一个利基的“JSX for Flutter”实现之外的任何东西,它就必须解决,并且它需要一些_巧妙的_修改才能使 DSX 真正工作不会让它过于臃肿而无法证明它在视觉上更简洁。

并且为了解决“DSX 只是 Dart,如果 DSX 不能做某事,就使用 Dart”的反驳,那么我的反驳将是,每当我遇到 DSX 没有的场景时,我必须继续退回到 Dart' t 处理,那为什么我不应该一直使用 Dart 呢?

并且为了解决对“如果你愿意,你可以,DSX 只是一个选择”的反驳那么你真的在卖空自己。 即使它真的只是“一种选择”,它仍然需要带来一些东西来说服人们使用它。 你自己说过 DSX 不是 JSX,所以只想要 JSX 的人不会得到他们想要的东西。 意味着除了“类似 JSX 的吸引力”之外,还需要一些切实的理由让人们想要使用它。

如果您只是在构建自己想要使用的工具,那么这一切都是没有意义的,您可能会发疯。 但是,如果您实际上是在构建您打算供其他人使用的东西,那么您需要将它以您认为他们应该使用的可靠形式表达出来。

Web 组件是动物,死了但仍在行走; 它们与加拿大的袋鼠一样普遍。 我可以继续几天,但为了避免离题......

有点跑题了,但我想指出的是,Web 组件确实是一个很有前途的未来展望,即使添加对它们的支持比 tar 慢。 可以这样想:React 做了它所做的,因为它本质上实现了仅在 Javascript 中实现 Web 组件的想法。 想象一下,如果浏览器支持这些功能并受益于非沙盒性能并且不必通过 DOM 操作进行操作,那该有多好? (当然可能还要再等 20 年才能找到答案,但仍然……)

@andrewackerman

对不起,伙计,我没有时间无休止地争论并一遍又一遍地重复我之前说过的话; 无论如何,我们最终不会达成协议,所以祝你的 FLUI 好运。

您已经雄辩地谈论了它可以做什么以及将能够做什么,但我们实际上所看到的只是一小部分专门构建的代码片段以及您所说的它们是由转译器生成的。

在线 DSX 转译器已于 2018 年 2 月上线,任何人都可以使用它,因此无需相信我的话。 按“编译”,它会编译左侧面板上的内容并将结果放在右侧面板上。 打开调试器,您将看到写出的 AST。
https://spark-heroku-dsx.herokuapp.com/index.html

问题在于,JSX 是建立在像 JavaScript 这样的弱类型动态语言上的,而 DSX 是建立在像 Dart 这样的强类型静态语言上的。

它根本没有什么大的区别,就像“类”的 OOP(面向对象编程)概念和语法一样。 在无类型 Javascript 或有类型的 Dart 中几乎相同; 'if' 语句、'for' 语句等也可以这样说

它仍然需要带来一些东西来说服人们使用它。

显然这张票已经可以容纳 100 人了; 这比我使用它大 100 倍; 对我来说已经足够好了。

@cbazza

对不起,伙计,我没有时间无休止地争论并一遍又一遍地重复我之前说过的话; 无论如何,我们最终不会达成协议,所以祝你的 FLUI 好运。

我不是为了争论或因为一些根深蒂固的反 JSX 偏见而与你争论。 我试图让你回答需要回答的问题。 您正在开发一种您可能打算供其他人使用的工具,但您仍然没有提供令人信服的理由_为什么_他们应该使用它,而不是“熟悉”和“因为它更好”的模糊和主观好处。 前者,正如我之前所说,不一定是好事,而后者至今仍是一个没有任何实际支持的主张。

如果您希望您的工具取得成功,则需要将您正在做什么以及为什么这样做,并且您需要以一种可以轻松传达给他人的方式来做到这一点。 这并不是说你不能制作一个产品,除非它被_每个人_喜欢,但清晰而简洁的目标对于塑造设计和实施至关重要。 否则,你最终只会得到一个无方向的实用程序,它充其量只是一个利基产品,如果它最终出现在任何规模的生产代码中,那将是非常幸运的。

在线 DSX 转译器已于 2018 年 2 月上线,任何人都可以使用它,因此无需相信我的话。 按“编译”,它会编译左侧面板上的内容并将结果放在右侧面板上。 打开调试器,您将看到写出的 AST。

我什至没有看到该链接是一个有效的示例。 我以前从未使用过herokuapp,它看起来只是一个要点或其他东西,所以这取决于我。 :P

(尽管我会指出,修补在线沙箱与在更实际的环境中测试转译器不同。)

它根本没有什么大的区别,就像“类”的 OOP(面向对象编程)概念和语法一样。 在无类型 Javascript 或有类型的 Dart 中几乎相同; 'if' 语句、'for' 语句等也可以这样说

您已经不得不处理child strong-typing中的一个这样的差异。 那么属性强类型呢? 不同库中同名的小部件呢? 如果有人使用多个无名位置参数制作小部件会发生什么? 如果我们导入两个具有相同名称的小部件的库会发生什么? 在某些我没有想到的场景中会发生什么,以进一步展示 Javascript 和 Dart 等系统之间的内在差异? 我不得不说,你在这个讨论点上如此轻率让我担心 DSX 在现实环境中的寿命。

显然这张票已经可以容纳 100 人了; 这比我使用它大 100 倍; 对我来说已经足够好了。

同样,有 100 人基于“在 dart 代码中考虑类似 JSX 的语法”支持该问题。 他们投票是因为他们想要 _JSX_,而且正如您一直热衷于指出的那样,DSX 不是 JSX。 那么他们为什么还要使用 DSX 呢? 因为内联类似 XML 的 UI 声明是“未来”? 再说一次,我只是没看到。

我们已经在 Vue 中介绍了 JSX,但没有受到任何关注,但您链接的 Web 组件文章中还提到了两个 React 替代方案:Inferno 和 Preact。 据我所知,尽管它们本身也支持类似 JSX 的语法,但它们在基于 JS 的 Web 应用程序开发世界中都没有掀起任何波澜。 我真的认为人们需要对_究竟为什么_人们喜欢 React 中的 JSX 进行长期而认真的研究,因为从各方面来看,这似乎并不是因为 JSX 本身。 如果可以回答那个问题,那么我们就可以朝着“未来”的创新前进,而不是仅仅将我们喜欢的那个库中的一个特性带到我们个人认为应该存在的其他任何地方。

想想在这次讨论中投入了多少精力,以及可以做些什么来改进当前的框架,这让我感到难过。

@andrewackerman

问题在于,JSX 是建立在像 JavaScript 这样的弱类型动态语言上的,而 DSX 是建立在像 Dart 这样的强类型静态语言上的。

抱歉,但这不是问题。 此外,这根本没有任何意义。 除此之外,我们使用 JSX 和 TypeScript。

@escamoteur绝对!

@escamoteur我和你在一起。 _100._

@贝索诺夫

抱歉,但这不是问题。 此外,这根本没有任何意义。 除此之外,我们使用 JSX 和 TypeScript。

React 不是为 TypeScript 设计的。 它是为 Javascript 设计的。 所有的小部件定义、属性、属性和其他一切都是为了在 JavaScript 的动态环境中使用而设计的,因此 TypeScript 的类型安全不会为 JSX 与 React 的交互方式引入任何新因素。 这是 JSX 是如何设计用于与 Flutter 完全不同的设置的又一个示例。

@andrewackerman
为什么你认为这很重要? JSX 是一种描述接口的方式。 它本身与语言无关。 看这里。 它不是 JavaScript。 但是,为什么不能用 JSX 来完成呢? (除此之外(还)没有实现)

而且..你知道...流量也来自fb:

Flow 是 JavaScript 的静态类型检查器。

请停止出售支持和反对您从未使用过的扩展的论据。 我每天都使用 JSX,我对它的 ATM 很满意,尽管我对此持怀疑态度。 我可以想象,JSX 会以其他模式发展,就像 AngularJS 一样。

也许这个主题有助于为 Dart 找到更好的模式? DSX 只是一个提议。 查看上面的构建器模式示例或此处提供的其他语言调整。 而且,好吧,也许你的flui是更好的方法? 我不知道。 但是让我们找出来并互相帮助以改进他们的建议,而不是讨论别人建议中的坏事。

我想建议关闭这个话题,并在有限的对话中打开新的总括话题。 所有改进方式的建议,如何使用颤振,客观地讨论自己的话题,爱不恨。

是的,这里的仇恨是史诗般的,只要考虑一下:
有 3587 张开票,如果你按“大拇指向下”对它们进行排序,你会得到
1(这个)有 57 个“大拇指向下”
3586(其他票)有 1 个或更少的“大拇指向下”

@贝索诺夫

为什么你认为这很重要? JSX 是一种描述接口的方式。 它本身与语言无关。 看这里。 它不是 JavaScript。 但是,为什么不能用 JSX 来完成呢? (除此之外(还)没有实现)

这是一种描述 UI _in Javascript_ 的方式(因此名称中的“JS”部分)。 不,因为它是一个内联的 DSL,它_not_ 与语言无关。 即使是这样,这仍然不能使它成为“更好的选择”,因为那里有很多真正与语言无关的 DSL,它们对于 UI 声明来说是非常不合适的。

而且..你知道...流量也来自fb:

Flow 就像 TypeScript:一个用于 Javascript 的静态类型检查系统。 它不是一个 React 工具,也不是 React 设计为与它一起使用的。 React 首先是一个 Javascript 库,而 JSX 旨在与 React 一起使用。 无论在 React 开发中引入什么辅助工具和实用程序,最终都与 React+JSX 互操作性无关。

请停止出售支持和反对您从未使用过的扩展的论据。 我每天都使用 JSX,我对它的 ATM 很满意,尽管我对此持怀疑态度。 我可以想象,JSX 会以其他模式发展,就像 AngularJS 一样。

我使用过 JSX,虽然我对它有个人意见,但我故意将这些意见排除在讨论之外。 实际上,如果您阅读了我之前的评论,您就会知道我曾称赞 JSX 在 React 中彻底改变了 UI 开发。 除了我对 JSX 整体市场渗透率的一些温和的评论外,我的论点一直是关于 JSX _in Flutter_。 而在这个话题上,并没有确定 DSX 功效的实际依据,所以我们所能做的就是检查 JSX 在其他地方是如何实现的,而这种检查并不是好兆头。

当然,除非您也每天都在使用 DSX,并且可以启发我们在 Flutter 中使用 DSX 的实际优势?

也许这个主题有助于为 Dart 找到更好的模式? DSX 只是一个提议。 查看上面的构建器模式示例或此处提供的其他语言调整。 而且,好吧,也许你的flui是更好的方法? 我不知道。 但是让我们找出来并互相帮助以改进他们的建议,而不是讨论别人建议中的坏事。

_这就是我正在做的事情。_ DSX 被提议作为熟悉 JSX 的人的 UI 解决方案。 JSX 中有一些关键设计元素旨在用于与 Dart 和 Flutter 完全不同的环境。 _为了让 DSX 成功,需要解决这些差异。_ 我不是一个 _hater_。 我正在努力促进建设性的讨论并提出重要的问题。 然而,我得到的所有回应都只是主观的重言式(“JSX 是好的,因为它是未来,它是未来,因为它是好的”),对关键设计点不屑一顾(“DSX 不需要考虑JS 和 Dart 之间的差异,因为没有任何”),或者只是单纯的敌对(“你显然不喜欢 JSX,所以不要再谈论 DSX”)。

你不能仅仅依靠纯粹的赞美来制作成功的产品。 它也需要经得起批评并承担责任。 人们出现并说“OMG 是的,请制作 DSX”虽然令人振奋,但并没有帮助。 在这个帖子中,有几个人对 DSX 提出了完全有效的批评,无论是最初的设计还是整个概念。 在大多数情况下,这些批评中的许多还没有得到直接解决,普遍的态度是不屑一顾。

我唯一担心的是,所有这些对 JSX 无条件的热爱阻碍了人们客观地看待 DSX。 我明白为什么你们想要 Flutter 中的 JSX 之类的东西,我可以联系起来——我认为 Flutter 需要一个专用的 UI DSL 是我创建 Flui 的原因。 但是,如果唯一被允许谈论 DSX 的人是对它无话可说的人,那么它_将_失败。

我们可以重新讨论这个话题吗?
事实上,我认为没有任何理由让这个问题保持开放。

Dart 团队表示他们还有其他优先事项。 并且专业 JSX 方面自愿做出自己的 DSX 实现

也许我们应该只拥有一些提出不同解决方案的开源存储库(即使几乎没有工作)。 例如 DSX 或模板。
然后考虑从 Flutter 的自述文件或 awesome_flutter 重定向到这些 repos。 如果有任何东西阻碍了 DSX 的实施,请创建另一个有关细节的问题。

然后让社区完成它的工作。

让它保持打开状态,因为人们会继续打开新的请求 JSX 的票(因为它之前已经发生过两次)。

让它保持打开状态,因为人们会继续打开新的请求 JSX 的票(因为它之前已经发生过两次)。

这里的不同之处在于我们现在可以回答以下问题:

“我们目前不打算在 dart/flutter 中实现这一点。但你可以看看社区替代方案 [here] 和 [there] 或阅读 [this issue]”

并将问题作为重复项关闭。

一个评论和投票的地方,它就在这里。 对类似 JSX 的功能的请求并没有消失,并且票证已打开,因为它需要 Flutter 工具支持(编译器和 VS Code IDE),并且我已使用此信息(第一条评论)更新了票证请求。 如果大量的人开始要求这样做,它将激励 Flutter 团队投入资源。

看起来这里的大部分争议都不是围绕 JSX,而是围绕 DSX。 我建议将 DSX 讨论拆分到它自己的线程中,并将这个泛型留给 JSX。

最后,DSX 只是接近 JSX 的一种方式,所以无论如何我们都不应该将这两个讨论混合在一个线程中。

大不,我真的认为只有 1 种语言是一个很大的收获,jsx 语法会带来更多的东西,比如 xml 和 js 的分离等等......不好。

这就是我的意见。

这是我见过的最长且毫无意义的 Github 问题。

@cbazza 干得好👍
DSX + 1

@BarryYan ,谢谢

请避免这种评论,无论是“+1”还是“谢谢”。
这会向所有订阅者发送一封电子邮件,毫无意义。

请避免这种评论,无论是“+1”还是“谢谢”。
这会向所有订阅者发送一封电子邮件,毫无意义。

对你来说没有什么有趣的!!!
请避免告诉人们他们能说什么或做什么,只关注你能说什么或做什么。

@cbazza

哥们,这是基本的礼仪。 此线程上的任何新消息都会通过电子邮件发送给每个订阅它的人,因此发布无助于讨论的评论是不礼貌的,因为它会无缘无故地惹恼人们。 像“+1”和“谢谢”这样的基本反应可以通过一个简单的竖起大拇指反应来传达,所以就这样做吧。

话虽这么说,如果这个帖子真的变成争论某人是否应该发布“+1”消息,这是一个很大的危险信号,所有建设性的讨论已经正式结束,它真的应该关闭(也许是永久的)这次)。

@andrewackerman

明白了,但是当你这样做时,也许你还应该考虑基本的礼仪,同时用你的小说(长篇和虚构写作)来爆破这个话题。

请停止用你一连串毫无意义的问题(你知道,在墙上扔尽可能多的废话,看看是否有任何问题)和要求来传播 FUD(恐惧不确定性和怀疑)。

毕竟您的所有著作都没有为 DSX 增加任何价值,所以我没有兴趣与您讨论这个主题。 不过你的动机很明显,在爆破 DSX 的同时宣传 FLUI。

告诉我一些事情,当您将自己的问题应用于 FLUI 时,您有答案吗? 让我们讨论一下 FLUI 好吗?

@cbazza

明白了,但是当你这样做时,也许你还应该考虑基本的礼仪,同时用你的小说(长篇和虚构写作)来爆破这个话题。

你提到我的回答,我花了很多时间和精力来做到深思熟虑和公正,因为我可以把它们写成“长篇和虚构的写作”,这说明了很多关于你的性格和你是如何接近的本次讨论。 我试图推动围绕 Flutter 中任何 JSX 实现的非常现实的问题展开讨论,而你则以任何形式的相反意见抨击任何人。 我们谁是基本礼仪的更大罪犯?

请停止用你一连串毫无意义的问题(你知道,在墙上扔尽可能多的废话,看看是否有任何问题)和要求来传播 FUD(恐惧不确定性和怀疑)。

我唯一“要求”的是,您解决许多人提出的有关 DSX 的众多问题,而不仅仅是挥手或公开敌意。 对于提议对 Flutter 的功能集进行重大更改/添加的人,我觉得这不是一个不合理的期望。

毕竟您的所有著作都没有为 DSX 增加任何价值,所以我没有兴趣与您讨论这个主题。 不过你的动机很明显,在爆破 DSX 的同时宣传 FLUI。

我要求_你_捍卫你的立场。 您反复说 JSX/DSX 是最好的/未来的,但尚未解释如何或为什么。 有几个人表达了对 DSX 的合理担忧,但您没有解决这些问题,而是躲在“如果您不喜欢它,就不要使用它”的反驳背后,从而挥之不去。 我的“动机”是让你回答关于_任何_技术项目需要提出的问题,首先是为什么人们应该使用它而不是替代品。 (正如我之前解释的那样,熟悉并不是一个足够好的理由。)

就 FLUI 而言,我所做的只是为整体问题(Flutter 的 UI 声明性语法)提出一个替代解决方案,同时要求人们对它做同样的事情,就像我对 DSX 所做的那样——提供真诚和建设性的批评。 我并不是说 FLUI 在客观上比 DSX 更好——我提出了一种由不同的 UI 开发方法形成的替代方案,并要求人们形成自己的意见。

(我还想指出,除了我最初提到我提出了一种可能的 GUI 表示替代方法之外,我唯一一次谈论 FLUI 就是当你提出它的时候。那么它是如何当你谈论它比我更多时,我的别有用心是宣传它是有道理的?)

告诉我一些事情,当您将自己的问题应用于 FLUI 时,您有答案吗? 让我们讨论一下 FLUI 好吗?

FLUI 不是 DSX - 它不必回答我向您提出的关于 DSX 的_每一个_问题,因为其中许多问题都是针对 DSX 的设计的。 不过,这并不是说它没有自己的一系列问题需要回答,不,我没有所有这些答案。 这就是_为什么_我重视批判性讨论 - FLUI/DSX 不会在公众舆论的法庭上站起来,除非他们能幸免于难。 不过,这不是讨论 FLUI 的合适场所。 如果您想详细讨论 FLUI,该项目有自己的问题板,所以请随时在那里发帖。

你没有回应批评,而是采取了防御和回避的态度,以至于你直接对两个不同的场合(接近三个)负责,因为事情变得太激烈,这个帖子不得不暂时关闭。 所以我要打破“礼仪”,说一次:搁置你的自我,停止将批评解释为人身攻击,并回答重要问题。 要么这样,要么与 DSX 和平相处,从未起步。

安德鲁瓦克曼干得好👍
+ 1

@andrewackerman

做得好

伙计,你得到了@jstansbe的赞美,它传达了比竖起大拇指更多的信息,而你对赞美不屑一顾?

显然你没有把我关于长度的暗示放在心上,但不要对我的性格下结论,因为你根本不认识我。

你提到我的回答,我花了很多时间和精力来尽可能地深思熟虑和公正

我很感激,我阅读了你所有的“长文”,回答了所有问题:没办法,但是当我正确回答时,你不理解我的回答,并得出结论认为我不屑一顾。

对我来说很明显你对 JSX 不是很有经验,你真的不明白它是如何工作的。 因此,与其加倍拥有它,我将更详细地解释它。 例如 JSX & DSX 只做以下 2 种转换(之前提到过几次):

(1)
<A property="a" />
    becomes
new A(property: a)

(2)
<A property="a">
  <B />
  <C />
</A>
    becomes
new A(property: a, children: <Widget>[new B(), new C()])

其他一切都由宿主语言处理,例如:它如何处理同名组件的导入; 答案:宿主语言。 我不是不屑一顾,这是它的设计方式和它的力量来源。 您会看到是否将标记和编程分离到单独的文件中,您开始使用“if”的简单构造来复制标记内部的编程,等等。您最终在标记内部构建了一种声明性编程语言,它永远不会像主要编程语言。 因此,通过将标记引入编程语言,您将拥有两全其美的优势,这就是 JSX/DSX 的强大之处。

请注意上面 (2) 中的转换硬编码<Widget>并且情况并非总是如此,因此现在您可以按照前面讨论的那样在需要时指定它。 查看转换,现在所有符号都来自源或可以指定,因此将来不会有一些主要的魔法陷阱。

当你以任何形式的相反意见抨击任何人时。

这不是真的,你可以有相反的意见,但当我可以证明不是这样时,你不能声称某事是真的。

对于提议对 Flutter 的功能集进行重大更改/添加的人,我觉得这不是一个不合理的期望。

但这就是问题所在,我希望 Flutter 团队实现 DSX,但后来我做到了,所以他们需要实现的是不依赖 DSX 的通用东西,而 DSX 不是唯一的受益者。 浏览器 js 引擎支持源映射,这使得浏览器中的新语言生态系统能够转译为 js; 它启用了 Dart 的创建! 和其他几个(Coffeescript、Typescript、Reason 等)。 Dart 现在可以做同样的事情,并从它帮助建立的生态系统中受益,所有船只都在上升。

我要求你捍卫你的立场。

我已经做过很多次了,结论是 Plain Dart 或 DSX 归结为用户偏好; 重要的是提供选择而不是强迫人们以一种方式。

首先是为什么人们应该使用它而不是替代品。

我会使用 DSX,因为我更喜欢它,比如空格或制表符,在变量名之前或之后键入定义。 为它而战是没有意义的,只是接受人们有不同的喜好; 那里有不止 1 个编程编辑器吗?

熟悉不是一个足够好的理由

只是您的意见,为什么我们几乎在每种语言中都使用“if”语句,“for”语句,“class”,现在是“asyn/await”。

不过,这不是讨论 FLUI 的合适场所。 如果您想详细讨论 FLUI,该项目有自己的问题板,因此请随时在此处发布。

很好,现在你赢得了我的尊重。

你直接负责两个不同的场合(接近三个),由于事情变得太热,这个线程不得不暂时关闭。

事情是即使它再次关闭,它也不会阻止人们要求类似 JSX 的功能。

搁置你的自我,停止将批评解释为人身攻击,并回答重要问题。

我没有自我,但我确实脾气暴躁,所以当有人惹我生气时不会弄错(它马上就出来了)。 不想冒犯你,但你的问题并不重要。

要么这样,要么与 DSX 和平相处,从未起步。

你不是衡量成功的标准,你不知道我在做什么。

伙计,你得到了@jstansbe的赞美,它传达了比竖起大拇指更多的信息,而你对赞美不屑一顾?

您显然没有注意到他评论中固有的讽刺意味。 (他确实做了我说不要做的一切。)虽然我可以欣赏一些有趣的拖钓,但在这里不合适。 如果碰巧他是真诚的,那么我为我的冷嘲热讽道歉,但我的观点仍然存在——这种评论在这里_仍然_不合适。

对我来说很明显你对 JSX 不是很有经验......

我在对这个线程的第一个评论中的免责声明可能会提示你吗?

......你真的不明白它是如何工作的。

你认为我对 JSX 没有太多经验,而我根本不知道它是如何工作的? 虽然我从未参与过任何严肃的 React 项目,但我已经完成了相当一部分的修补工作。 我完全理解它是如何工作的。

其他一切都由宿主语言处理,例如:它如何处理同名组件的导入; 答案:宿主语言。

这在标记语言和宿主语言不同的情况下是有意义的。 使用 JSX,标记语言被设计为宿主语言的 _extension_。 因此,JSX 被设计为 JS 的扩展,这就是它工作得如此出色的原因。 DSX 是 Dart 的 JSX 实现。

你没有看到那里的问题吗? 一种标记语言,设计为一种语言的扩展,被杰里操纵成另一种根本不同的语言。 不可避免地会出现大量问题、边缘情况和注意事项。

您会看到是否将标记和编程分离到单独的文件中,您开始使用“if”的简单构造来复制标记内部的编程,等等。您最终在标记内部构建了一种声明性编程语言,它永远不会像主要编程语言。

首先,分离标记和编程背后的整个想法是,如果你做得正确,那么两者之间就会有明显的分离,这会导致_no_重复。

其次,如果您在 UI 代码中执行的操作比iffor更复杂(这些结构可以在许多标记解决方案中轻松处理),那么我认为无论如何,这表明您的设计有问题。 根据 MVC/MVVM 设计原则,如果您在 UI 结构中加入了复杂的逻辑,这可能是代码有问题的迹象,无论如何您都应该认真考虑重新设计。

(这并不是说您_不能_使用 JSX 以 MVVM 方式编写声明性 UI,但这只是为了一点客观收益而招来麻烦。为什么要使用您_可以_编写符合标准的代码的东西,而您可以使用使编写_不是_的代码变得困难的东西?)

这不是真的,你可以有相反的意见,但当我可以证明不是这样时,你不能声称某事是真的。

你还没有“证明”什么。 你已经给出了一堆尚未得到任何证实逻辑支持的主观主张。 (尽管值得称赞的是,这篇最新帖子是一个很大的改进。)

但这就是问题所在,我希望 Flutter 团队实现 DSX,但后来我做到了,所以他们需要实现的是不依赖 DSX 的通用东西,而 DSX 不是唯一的受益者。

你仍然要求他们做不平凡的事情,所以你有责任说服他们和我们其他人为什么他们应该这样做,为什么他们应该把其他事情推到他们的待办事项清单上。

浏览器 js 引擎支持源映射,这使得浏览器中的新语言生态系统能够转译为 js; 它启用了 Dart 的创建!

JS 本身的本质就是这样的事情很容易实现(相对而言),以至于 Dart 远非唯一具有 JS 转译器的语言。 正如我多次指出的,Dart 不是 JS。 它是静态的和强类型的,这意味着很多在 JS 中很容易做的事情在 Dart 中却非常复杂。

我会使用 DSX,因为我更喜欢它,比如空格或制表符,在变量名之前或之后键入定义。 为它而战是没有意义的,只是接受人们有不同的喜好; 那里有不止 1 个编程编辑器吗?

按照这种逻辑,我应该制作一个 UI 解决方案,您可以在其中使用十六进制编码的盲文定义构造。 我的意思是,如果真正重要的是个人喜好,我只需要说“有些人喜欢它”来捍卫它的存在,对吧?

您正在开发一个打算供其他人使用的工具,因此您需要超越“某些人可能会喜欢它”的推理来使自己具有说服力。 如果你不能用语言表达_为什么_他们应该使用它而不是其他东西,那么是什么让你相信他们会这样做? 在设计 DSX 的功能集时,有什么可以激励您_确保_他们会这样做?

只是你的意见,为什么我们在几乎所有语言中都使用“if”语句,“for”语句,“class”,现在是“async/await”。

首先,这些关键字(除了async/await )成为常见的编程词典,因为 C 和 BASIC 等语言在过去几十年中非常流行。 正如我之前提到的,JSX 的寿命远未得到证明——它已经存在了 5 年,尽管有可用的选项,但在 React 之外还没有看到任何重要的用途。

其次,熟悉和约定之间有很大的不同。 if , while , for , struct , class , enum , try/catch/finally , async/await ...这些都是口头表达概念的好方法。 有理由捍卫使用那些人们熟悉的关键字之外的关键字——它们在概念上是有意义的。 (当然,这并不意味着它们是常量。有些语言是if ... then 。有些是if ... elif ,有些是if ... else if ,还有一些是if...endif 。有些是foreach ,有些是from 。等等。)

同时,因为“熟悉”而使用 JSX 的论点不属于同一类别。 JSX 是表示声明式 UI 的一种方式,但它既不是唯一的方式,也不是最流行的方式。 此外,它被设计为在一种环境中使用,因此在另一种环境中使用它可能会使熟悉度变成一件坏事——熟悉度使他们期望它的工作方式或多或少与它在其他地方的工作方式完全相同,所以如果它那么这不会导致精神上的脱节,这是您想要_避免_的事情。

事情是即使它再次关闭,它也不会阻止人们要求类似 JSX 的功能。

无论如何,他们都要求它,并且问题仍然被重定向到这里。 我看不出被关闭的线程会如何改变这一点。

你不是衡量成功的标准,你不知道我在做什么。

阅读任何有关产品设计的书籍。 第一章总是关于创建一个声明、宣言、口号,用简单的英语描述产品是什么以及人们为什么应该关心它的任何有形和可表达的东西。 给业余企业家的最常见建议形式是进行“电梯推销”,这是有原因的,可以在 30 秒或更短的时间内清晰简洁地传达产品和平局。 如果你不能简明扼要地说明为什么人们应该使用你的产品,这表明它正在遭受身份危机。 如果设计产品的人不能充分回应批评,那么就会给人一种对自己的产品缺乏信心的印象。 这两件事对投资者来说都是巨大的危险信号。

在这种情况下,产品是 DSX,投资者是考虑使用它的开发人员。 您唯一支持您的人显然会无条件地为描述中带有“JSX”的任何内容欢呼。 我在这个线程中看到的每个其他人都在质疑你在做什么,在你的回答之后似乎不相信。

您目前处于或接近 0% 的转化率,当我说您尚未对批评做出充分回应时,这就是我的来历。 也许你不在乎,但如果你真的打算让 DSX 成为一个可用于实际项目的 UI 声明标记插件,你可能想要开始。

但话又说回来,也许你是个例外。

好的,这次对话已经远远超出了我们认为在 Flutter 社区中可接受的讨论类型,因此我将锁定此线程并关闭错误。 请考虑阅读https://flutter.io/design-principles/#conflict -resolution 以了解有关我们在此处的行为方式的更多详细信息。

如果有人想贡献代码来解决这个问题,下一步将是提出如何进行构建系统集成的设计,以便我们可以使用 Gradle、Xcode、热重载和与现有应用程序集成进行代码生成工作。 如果有人对此感兴趣,请随时与我联系。 否则,我希望这是我们明年初将开展的工作。 一旦我们有了这样做的机制,像 DSX 这样的解决方案将很容易集成到 Flutter 生态系统中。 我们甚至可以找到应该默认集成的解决方案。 与此同时,我们也在努力改进 Dart 的语法,看看我们是否可以让 UI 表达式更容易编写。

我想要求人们不要在这个主题上打开新的错误,除非有一些非常有建设性和新的东西值得提出。

此页面是否有帮助?
0 / 5 - 0 等级