我有一个解决这个问题的方法,站在 Günter Zöchbauer 的肩膀上(上面的评论)。我的目标是以只读方式将一个字段值“绑定”到两个。我们还没有完全做到这一点,但是这条途径本身就是教育性的。
观察者法
这个解决方案是我为自己设定的目标的一种解决方法。我在这段代码上做了一些注释来解释我看到了什么,或者我认为为什么会发生。
目的是让 fullName 以如下形式显示两个名称:
参考表格.html:
<polymer-element name="reference-form" extends="form" >
<template>
<style> ... </style>
<div id="slambookform" >
<div class="entry">
<label>Author:</label>
<input type="text" value="{{theData['givenName']}}" >
<input type="text" value="{{familyName}}">
</div>
:
<div class="entry">
<label>Full name:</label>
<input disabled type="text" value="{{fullName}}" >
</div>
:
</div>
<template>
</polymer-element>
表单属性的代码,Polymer-dart 使用小胡子语法“{{fullName}}”绑定到 HTML 的东西。为了简单起见,我只使用了一个 'notifier' 字段,这会更新 familyName 和 givenName 中的 fullName 字段em>。
reference_form.dart:
//---- testing ----
String _familyName; // (1)
@observable // (2)
String get familyName => _familyName; // (3)
void set familyName( String nam ){ // (4)
_familyName = nam;
fullName = notifyPropertyChange( // (5)
#fullName,
"${fullName}",
"${nam}, ${theData['givenName']}" );
}
@observable
String fullName; // (6)
//---- end: testing ----
私有成员“_familyName”是模板中使用的公共 familyName 属性的影子(上面的 sn-p)。
- 影子(私有)成员“_familyName”存储 familyName 伪属性的数据。
- 接下来的三行声明了一个@observable 属性,familyName
-
Get familyName。只需回显阴影变量的值即可。
-
SetfamilyName。更新阴影变量和复合 fullName 属性。
- 注意:合成格式可以完成两行:
_familyName = nam;
全名 = 南;
...但我们希望看到传播的所有更改,请参阅 (#5)。
-
notifyPropertyChange() 方法更新了 fullName 属性的所有 个观察者。
- 注意:我并没有在 Polymer 内部乱搞;在 Observable 类中,fullName 没有显示代码的观察者。
- 在我看到这个之前,我认为 Polymer 绑定到 HTML 模板是通过观察者(观察者)进行的,但似乎不是。我可能弄错了。在任何情况下,对“#fullName”符号的 notifyPropertyChange() 调用都不会更改此测试用例的结果。
- fullName 属性绑定到 Polymer 表单。
基本上,每次 familyName 发生更改时,{{fullName}} 值都会更新伪属性。
效率说明:
- 每次击键都会调用familyName 设置器(在调试时观察)。我理解这一点,并认为这并不总是最好的解决方案。
- 对我来说,我宁愿只在用户退出该字段时调用 setter。然而,当我使用 onblur 时,触发器是表单的模糊,而不是字段。
- 似乎我们都可以在性能方面受益,获得更多关于这些钩子、路径和任何可用选项的内部信息,以提高效率。
欢迎提出意见和改进。这个例子对我来说是一个解决方法,所以它绝对是一个正在进行的工作。 ;-)
封装方式
我正在根据上面的“观察者方法”开发一个更接近最初目标的解决方案。这种方法依赖于当前(即 Dart v4)对模块和库的使用。我会先展示工作代码,然后用注释解释有趣的东西。
reference_form.dart:
import 'package:exportable/exportable.dart'; // [1]
class _Data // [2]
extends Object with Exportable { // [3]
@export String publishDate; // [4]
@export String authorGivenName = '(given)';
@export String authorFamilyName = '(family)';
@export String authorUrl = '';
//--- attributes ---
String get fullName => "${authorFamilyName}, ${authorGivenName}"; // [5]
void set fullName( String nam ){ // [6]
//don't need this
}
//--- ctor ---
_Data(){
publishDate = new DateTime.now().toString(); // [7]
}
} //_Data
@CustomTag('reference-form')
class SlamBookComponent extends FormElement with Polymer, Observable {
SlamBookComponent.created() : super.created();
//---- testing ----
@observable
_Data data = new _Data(); // [8]
:
} //SlambookComponent
注意事项:
- 包含 Exportable mixin 以转换为 JSON。我没有导出“fullName”,因为它目前只是在格式化。
- 将 exportable 添加到您的 pubspec.yaml 和“Run Pub get”。
- “_Data”类是 reference_form.dart 模块私有的。我对范围规则做了一些测试,因为我不希望内部数据结构泄漏,当然除了像 JSON 这样的天主教(small-c)。
- 引入 Exportable 混合。
- 我已经测试了Exportable,它完全实现了我认为我必须自己编写的内容。对此感到满意。
- JSON 不是原始问题的要求;但我确实希望 (eventual) 解决方案成为可序列化或保存的一流人工制品,这在我的大多数用例中都很重要。
- 这是快速灵活地扩展 Dart 工具的一个很好的例子!
- 使用 @export 修饰符来识别特定字段,以交换为 JSON。
- 将 fullName 属性导出为 String (get)。
- 不需要设置操作。然而 Dart 显然坚持 Set 方法匹配 'get'。
- 我对此感到失望。我更喜欢我可以拥有只读属性和属性的想法,例如喜欢ruby。
- 经测试,Dart SDK v1.4.0;当匹配的 setter 未实现/声明时失败(??)。
- 使用构造函数设置日期数据属性的初始值。
- 将名为“data”的不透明公共属性声明为 (private) _Data 实例。
#8 点展示了dart 的强大方面,以启用对象的不透明实现,然而,您可以'deliver'/'share 没有具体内部细节的细节。
我已运行此代码并检查了这些概念是否适用于隐藏数据(_Data 类型)以及不透明的访问和序列化。此外,您不能意外查看内部私有类型(意外,尽管可能会出现显式黑客攻击)。我不会为接受 C/C++ 有意识的责任范式而道歉——我认为这是作为程序员最强大的方面; 我们对我们生成的代码产生的影响/错误负责。我建议在小型迷你用例中测试“bits 行为”。
我放了polymer 标记的例子;没什么奇怪的。对我来说,这种方法比原始(早期)Dart 教程更简洁,更面向对象
reference_form.html
<polymer-element name="reference-form" extends="form" >
<template>
<style> ... </style>
<div id="slambookform" >
<div class="entry">
<label>Author:</label>
<input type="text" value="{{data.authorGivenName}}" >
<input type="text" value="{{data.authorFamilyName}}">
</div>
<div class="entry">
<label>Published:</label>
<input type="date" value="{{data.publishDate}}">
</div>
</div>
</template>
<script type="application/dart" src="reference_form.dart"> </script>
</polymer-element>
在 Polymer 标记中可以知道(并且具有可见性)内部字段名称。 为什么?
... 因为“reference_form.html”和“reference_form.dart”通过 Polymer-dart。真的很不错;尽管“.dart”和“.html”组件似乎像 ASP.NET 和 C#/VN.NET 一样紧密耦合,因为(也)为方便指定(??)。我承认这是一个完全不同的主题。有事情要解决,要保留事情yar(游艇术语)。
无论如何,对我来说,我觉得从上面的封装混乱开始的方法更适合我对小型实用程序的需求。