dart-polymer:无法从事件处理程序设置属性

时间:2013-11-04 10:08:27

标签: dart polymer dart-polymer

以下代码不起作用。也许我做错了什么..请更正我的代码:

  1. 的index.html:
  2. <html>
    <head>
        <title>Page</title>
        <link rel="import" href="msg_box.html">
    </head>
    <body>
      <msg-box id="msg" caption="Caption 1"></msg-box>
      <button id="btn">click me</button>
    <script type="application/dart" src="index.dart"></script>
    <script src="packages/browser/dart.js"></script>
    </body>
    </html>
    
    import 'dart:html';
    import 'package:polymer/polymer.dart';
    import 'msg_box.dart';
    
    void main() {
      initPolymer();
    
      ButtonElement btn = querySelector("#btn");
    
      btn.onMouseEnter.listen((e) {
        MsgBoxElement elm = querySelector("#msg");
    
        window.alert(elm.caption); // SHOWS 'Caption 1'
    
        elm.caption = "Caption 2"; // DON'T WORK!
    
        window.alert(elm.caption); // SHOWS 'Caption 2', BUT PAGE SHOWS 'Caption 1'!!!
      });`
    }
    
    1. msg_box.html
    2. <polymer-element name="msg-box" attributes="caption">
        <template>
        <h4>{{caption}}</h4> 
        </template>
        <script type="application/dart" src="msg_box.dart"></script>
      </polymer-element>
      
      import 'package:polymer/polymer.dart';
      @CustomTag('msg-box')
      class MsgBoxElement extends PolymerElement {
        // fields
        String _caption;
        String get caption => _caption;
        void set caption(String value) {
          _caption = notifyPropertyChange(#caption, _caption, value);
        }
      
        MsgBoxElement.created() : super.created() {
        }
      }
      

      这个问题对我很重要。另请参阅https://code.google.com/p/dart/issues/detail?id=14753&sort=-id&colspec=ID%20Type%20Status%20Priority%20Area%20Milestone%20Owner%20Summary

2 个答案:

答案 0 :(得分:5)

我认为这里的问题是没有处理挂起的更改通知,因为您的代码没有在脏检查区域中运行。你可以做两件事来解决这个问题:

  • 在您更新Observable.dirtyCheck()后立即致电caption;或者,
  • 在脏检查区域内运行您的代码:
void main() {
  var dirtyCheckingZone = initPolymer();
  dirtyCheckingZone.run(() {
     ButtonElement btn = querySelector("#btn");
     btn.onMouseEnter.listen((e) {
       MsgBoxElement elm = querySelector("#msg");
       elm.caption = "Caption 2";
    });
  });
}

此区域确保在执行任何回调或侦听器之后,我们将为您调用Observable.dirtyCheck。这种方法稍微好于显式调用dirtyCheck,因为当我们编译部署时,我们会从脏检查切换到显式通知。 initPolymer返回的区域已更改为反映此内容。

另外注意:如果使用@published注释,可以简化上面的MsgBoxElement。这是为了表示属性既可以观察也可以作为元素的属性公开。

import 'package:polymer/polymer.dart';

@CustomTag('msg-box')
class MsgBoxElement extends PolymerElement {
  @published String caption;
  MsgBoxElement.created() : super.created();
}

答案 1 :(得分:1)

根据您的信息,似乎正在更新模型,但DOM未更新,很可能是因为未设置可观察元素。尝试将以下注释添加到msg_box dart代码中:

import 'package:polymer/polymer.dart';
@CustomTag('msg-box')
class MsgBoxElement extends PolymerElement {
  // fields
  @observable String _caption;
  @reflectable String get caption => _caption;
  @reflectable void set caption(String value) {
    _caption = notifyPropertyChange(#caption, _caption, value);
  }

  MsgBoxElement.created() : super.created() {
  }
}

请参阅有关Breaking change announcement属性的dart邮件列表中的@reflectable。另请参阅this discussion有关设置@observable getters

的信息