【问题标题】:Dart data binding from a parent custom element to attributes of a child custom element从父自定义元素到子自定义元素属性的 Dart 数据绑定
【发布时间】:2015-04-23 22:12:29
【问题描述】:

这是我今天更新到最新的 Dart 库时出现的一个问题。

子自定义元素是一个组合框。父自定义元素用不同的字符串列表填充它。

// child HTML
<polymer-element name="bx-icombo" attributes="aLabel aList aSelected">
  <template>
    <div class='outr' flex layout horizontal center>
      <label for='inp' flex end-justified>{{aLabel}}</label>
      <!-- wait until the data is available -->
      <template if='{{aList}}'>
        <paper-dropdown-menu id='inp' label='aLabel' valign='top' flex start-justified >
          <paper-dropdown class="dropdown">
            <core-menu id='m' class="menu" selected="{{aSelected}}">
              <template repeat='{{aList}}'>
                <paper-item name='{{}}'>{{}}</paper-item>
              </template>
            </core-menu>
          </paper-dropdown>
        </paper-dropdown-menu>
      </template>
    </div>
  </template>

  <script type='application/dart' src='bx_icombo.dart'></script>
</polymer-element>

//---------------------------------------------------------------
// child Dart
@CustomTag('bx-icombo')
class BxICombo extends PolymerElement {

  @PublishedProperty(reflect: true)  String       aLabel;
  @PublishedProperty(reflect: true)  List<String> aList;
  @PublishedProperty(reflect: true)  String       aSelected;

  BxICombo.created() : super.created();
  }

//---------------------------------------------------------------
// Parent HTML
<polymer-element name="tst-sigs">
  <template>
    <paper-dialog backdrop heading='Sigs' closeSelector=''>
      <bx-icombo aLabel='{{selectAsignal}}'
                 aList='{{sigsList}}'
                 aSelected='{{sigsSel}}'>
      </bx-icombo>
    </paper-dialog>
  </template>

  <script type='application/dart' src='tst_sigs.dart'></script>
</polymer-element>

//---------------------------------------------------------------
// Parent Dart
@CustomTag('tst-sigs')
class TstSigs extends PolymerElement {

  @observable List<String> sigsList = ['alpha', 'beta', 'gamma'];
  @observable String sigsSel;
  @observable String selectAsignal = 'Select a Signal';

  TstSigs.created() : super.created();
  }

//---------------------------------------------------------------

Dartium 报告:

Attributes on bx-icombo were data bound prior to Polymer upgrading the element. This may result in incorrect binding types. (:1)

那么必须改变什么? @PublishedProperty 或 @observable 或 @published 或 ...。我承认发现 @... 注释的迷宫非常不清楚。

版本是:

Dart: 1.9.3 (STABLE)
Dartium: 39.0.2171.99

和包:

analyzer 0.24.6 (0.25.0+1 available)
args 0.12.2+6 (0.13.0 available)
barback 0.15.2+4
browser 0.10.0+2
cli_util 0.0.1+1
code_transformers 0.2.8
collection 1.1.0
core_elements 0.7.1+2
csslib 0.12.0
dart_style 0.1.8
glob 1.0.4
html 0.12.1+1
ini 1.1.0
initialize 0.6.0+4
intl 0.12.2
js 0.3.0
logging 0.9.3 (0.10.0 available)
markdown 0.7.1+2
matcher 0.11.4+4 (0.12.0-alpha.0 available)
observe 0.13.0+2
paper_elements 0.7.1
path 1.3.5
petitparser 1.3.7
polymer 0.16.1+4
polymer_expressions 0.13.1
polymer_interop 0.1.0+2
pool 1.0.1
quiver 0.21.3
smoke 0.3.2
source_maps 0.10.0+2
source_span 1.1.2
stack_trace 1.3.1
string_scanner 0.1.3+1
template_binding 0.14.0+2
utf 0.9.0+2
watcher 0.9.5
web_components 0.11.2
when 0.2.0
which 0.1.3
yaml 2.1.2

最初,代码转换器的问题迫使 code_transformers &lt; 0.2.5 将聚合物限制为 0.16.0。看起来代码转换器的事情已经解决了,所以我已经删除了版本约束并将聚合物更新到 0.16.1。问题依然存在。

主要功能是

import  'package:polymer/polymer.dart';
import  'lib/bxglobs/bxGlobs.dart' as G;

void realMain() {
  // empty for this test
}

void main() {

  G.initGlobals();

  initPolymer().then((zone) => zone.run(() {
    Polymer.onReady.then((_) => realMain());
  }));
}

和 pubspec.yaml:

name: bxPoly
description: BX GUI
dependencies:
  core_elements: any
  ini: any
  intl: any
  js: any
  markdown: any
  paper_elements: any
  polymer: any
  code_transformers: any
transformers:
- polymer:
    entry_points:
    - web/test.html

【问题讨论】:

  • 我根据引用/未更改的源代码创建了一个项目,使用Dart 1.9.3 r45104时Dartium没有输出错误。能否请您更新帖子,说明使用了哪些版本的 Dart SDK、Dartium 和 Pub 包?
  • 那么您的main() 看起来如何?您的聚合物变压器配置如何?
  • if="{{aList}}" 应该是if="{{alist != null}}"。 Dart 不会自动转换为 bool 但我不知道 Polymer 表达式(从未尝试过)。
  • 谢谢。我按照您的建议更改了 aList 测试。程序行为没有变化;)
  • 抱歉,没有想法。

标签: dart dart-polymer


【解决方案1】:

此错误几乎总是由于元素以错误的顺序注册而发生。具体来说,父元素在子元素之前注册。

如果没有完全访问代码的权限,这很难诊断,但遵循这两个规则应该确保它不是问题:

  • 将每个聚合物元素放在自己的 html 文件中,将每个类放在自己的 dart 库中(使用部件尤其会导致问题)。
  • 确保您的元素导入其所有依赖项。

【讨论】:

  • 如何获得元素注册顺序的诊断转储? Dart 不强制导入所有依赖项吗?如果自定义元素来自基类,我是否需要导入基类的依赖项(编辑器会将额外的导入标记为未使用)?
【解决方案2】:

编辑

  <template if='{{aList != null}}'>
    <paper-dropdown-menu id='inp' label='aLabel' valign='top' flex start-justified >
      <paper-dropdown class="dropdown">
        <core-menu id='m' class="menu" selected="{{aSelected}}">
          <template repeat='{{a in aList}}'>
            <paper-item name='{{a}}'>{{a}}</paper-item>
          </template>
        </core-menu>
      </paper-dropdown>
    </paper-dropdown-menu>

原创

  • 如果你从一个元素的影子 DOM 绑定到它的类 @observable 就足够了。
  • 如果您想从元素外部绑定到属性,请使用@published。
  • 如果您想使用绑定属性的值,例如在 CSS 选择器中使用 @PublishedAttribute(reflect: true)。 reflect 表示属性值反映到 DOM,否则仅适用于 Polymer 和 Dart 代码。

我以前从未见过此错误消息。可能是 Polymer 初始化有问题。你有一个自定义的主?您可以将其添加到您的问题中吗?

class MyA extends PolymerElement {
  @observable 
  aobservable = 'obs';

  @published 
  apublished = 'pub';

  @PublishedAttribute(reflect: true)
  areflected = 'ref';
}
<polymer-element name="my-a">
  <template>
    <!-- doesn't work
    <my-b bobservable="{{aobservable}}"></my-b> -->

    <my-b bpublished="{{aobservable}}"></my-b>
    <my-b breflected="{{aobservable}}"></my-b>
    <!-- you can bind properties of MyA here no matter if 
         they are observable/published/reflected
         (even when they have no annotation but they will not
         be updated when the value changes) 

         You can bind only to published (reflected or not)
         attributes of MyB
    -->
  </template>
</polymer-element>

class MyB extends PolymerElement {
  @observable 
  bobservable = 'obs';

  @published 
  bpublished = 'pub';

  @PublishedAttribute(reflect: true)
  breflected = 'rep';
}
<polymer-element name="my-b">
  <template>
  </template>
</polymer-element>
<head>
  <style>
    // you can only address reflected attributes here
    my-a[areflected="ref"] {
      backgroundColor: red;
    }
  </style>
</head>
<body>
 <my-a></my-a>
</body>

【讨论】:

  • 感谢回复,但还是不清楚。 @observable 对孩子,父母,两者都足够了吗?如果只有一个,另一个会发生什么? @published 和 @PublishedAttribute(reflectOnTheMeaningOfLife:true) 也是如此:) 文档中充满了“it”和“this”,其中的含义只有作者知道。我将使示例更完整。有什么方法可以判断 Polymer 初始化是否成功完成?
  • 对简短而无用的评论表示歉意。所以当我按下返回时发布了评论。当我编辑评论以使其有用时,SO说已经过去了太多时间。
  • 我明白了。您的评论似乎真的毫无意义:D。我更新了我的答案。如果在元素中添加ready() 方法,Polymer 将在元素初始化完成时调用它。如果您想使用自己的 main 方法,请参阅stackoverflow.com/a/20982658/217408。我不鼓励使用自定义 main,因为它经常让用户感到困惑。如果您必须这样做,可能是因为您也使用 Angular.dart,请查看我的链接答案。
【解决方案3】:

这似乎是解决方案。基于调试而不是知识,所以要小心..

假设您的组件foo.dart 和foo.html 引用另一个组件bar.dart 和bar.html。例如,引用可能是:

barEl el = document.querySelector('bar');

显然你import bar.dart 在foo.dart 的顶部。你得到描述的错误,除非你也

<link rel="import" href="bar.html">

在foo.html 的顶部。尽管 bar.html 通常不会在 foo.html 中引用。

【讨论】:

  • 这可能只是因为这个额外的导入改变了@JakeMacDonald 解释的注册顺序
  • 如果 Jake 解释了如何确定注册顺序,那就太好了:)
猜你喜欢
  • 1970-01-01
  • 2017-06-29
  • 1970-01-01
  • 2015-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-22
相关资源
最近更新 更多