【问题标题】:Dart: How to bind to variables annotated with int via Web UI?Dart:如何通过 Web UI 绑定到用 int 注释的变量?
【发布时间】:2013-01-03 20:32:48
【问题描述】:

在将类作为数据记录处理时,Dart 的最佳实践是什么?

详细说明:在编写应用程序时,很可能会为表格行创建一个类。如

    class Item {  int itemid, String itemName, double score   }
    Item item = new Item();

这允许编译时捕获 Dart 中的任何拼写错误等。 (与使用依赖于 NoSuchMethod 的类不同。)

它还需要一个相应的字符串结构来绑定到 HTML,例如

    <input id="itemname" type="text" bind-value="itemEdit.itemName">

所以飞镖是:

    class ItemEdit { String itemId, String itemName, String score }
    ItemEdit itemEdit = new ItemEdit();

接下来我们需要一种从一个到另一个的方法,所以我们给 Item 添加一个方法

    fromStrings(ItemEdit ie) {
      itemid = ie.itemId == null ? null : int.parse(ie.itemId);
      itemName = ie.ItemName;
      score = ie.score == null ? null : double.parse(ie.score);
    }

反之亦然:

    toStrings(ItemEdit ie) {
      ie.itemid = itemId == null ? '' : ie.itemId.toString();
      ie. itemName = itemName == null ? '' : itemname; // Web_ui objects to nulls
      ie.score = score == null ? null : score.toStringAsFixed(2);
    }

另外,我们从数据库中获取 jason 数据,所以我们需要在 Item 中添加另一个方法:

    fromJson(final String j) {
      Map v = JSON.parse(j);
      itemid = v['itemid']; 
      itemname = v['itemname'];
      score = v['score'];
    }  

而且我们需要能够恢复为默认值:

    setDefaults() { itemId = 0; itemName = "New item"; score = 0; }

这种冗长让我感觉我又在写 COBOL!

这里缺少一些基本的东西——无论是在我的理解中,还是在 Dart/WebUI 库中。

我想写的是这样的

    class Item extends DataRecord {
      int itemid = 0,
      String itemName = 'New item',
      double score = 0.0;
    }

然后,无需进一步编码,就能写出诸如

之类的代码
    item.toStrings();
    ...
    item.fromStrings();
    ...
    item.fromJson(json);
    ...
    item.setDefaults(); // results in {0,'New item',0.0}

并且能够在 HTML 中编写:

    value="{{item.strings.score}}"

如果这是可能的,它会比我现在编写的代码更快、更简单、更清晰、更不容易出错。

【问题讨论】:

标签: dart dart-webui


【解决方案1】:

(完全公开,这个答案是在假设至少有一个错误将被修复的情况下编写的。见下文)

三个可能有帮助的建议。

  1. 使用命名构造函数来解析和创建对象。
  2. 在编码为 JSON 时利用 toJson()。
  3. 在 Web UI 中使用 bind-value-as-number

1) 命名构造函数

import 'dart:json' as json;

class Item {
  int itemid;
  String itemName;
  double score;

  Item.fromJson(String json) {
    Map data = json.parse(json);
    itemid = data['itemid'];
    itemName = data['itemName'];
    score = data['score'];
  }
}

2) 编码为 JSON

dart:json 库有一个 stringify 函数可以将对象转换为 JSON 字符串。如果算法遇到的对象不是字符串、空值、数字、布尔值或这些对象的集合,它将调用该对象的 toJson() 并期待 JSON 可编码的内容。

class Item {
  int itemid;
  String itemName;
  double score;

  Map toJson() {
    return {'itemid':itemid, 'itemName':itemName, 'score':score};
  }
}

3) 现在,话虽如此,听起来您想轻松绑定到 HTML 字段并获取原始值,而不仅仅是字符串。试试这个:

<input type="number" min="1" bind-value-as-number="myInt" />

(请注意,此功能似乎存在错误。请参阅https://github.com/dart-lang/web-ui/issues/317) (来自https://groups.google.com/a/dartlang.org/forum/#!topic/web-ui/8JEAA5OxJOc

【讨论】:

  • 1) 这是一个简洁的功能,但并没有切入问题的核心——它还复制了字段名称、引号内等等。那不是漂亮的代码。 2) 是的,json 库很好。但同样,字段名称在您的代码中重复,再次在引号内。 3) 是的——也不是。这将是缓解某些问题的第二奖。我想要的是能够简洁地定义一个数据记录,每个字段名称只输入一次,其他一切都得到照顾。包括电池!
  • 不确定这个问题的重命名标题是否反映了它的真正含义......
  • 你可以试试 Chris Buckett 的 JsonObject 包,它使用 noSuchMethod 为你处理解析。请参阅dartlang.org/articles/json-web-service 了解更多信息。在镜像在 dart2js 中工作之前,我认为必须有一些代码重复。或者,可以编写一个代码生成库来处理样板文件。
  • 我重命名了标题以使其更加具体。我知道你在问一个广泛的问题。唉,Dart 还没有提供完整的端到端完全 DRY 解决方案。但在那之前,我们可以尝试让它变得更好一些。随意重命名标题。
  • 看来我没有重命名标题的权限/投票 :( 我认为 DRY 是 Dart 语言的关键特征 - 这是在任何地方讨论的特定问题,还是我应该在 code.google.com 上将其作为问题提出吗?
【解决方案2】:

刚刚找到了一种可能对这种情况有所帮助的方法:

      class obj {
        int gapX;
        String get gapXStr => gapX.toString();
               set gapXStr(String s) => gapX = int.Parse(s);
      ...

现在,您可以使用 HTML,例如

    bind-value="gapXStr"

在代码中你可以使用

    x += ob.gapX;

【讨论】:

  • 如果 DART 自动实现 .AsString 以像上面那样为 num 类工作不是很好吗!?
猜你喜欢
  • 2013-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-15
  • 2023-03-28
  • 1970-01-01
相关资源
最近更新 更多