2013-11-04 8 views
5

Der folgende Code funktioniert nicht. Vielleicht mache ich etwas falsch .. Bitte korrigieren Sie meinen Code:Dart-Polymer: kann kein Attribut aus einem Event-Handler setzen

  1. index.html:
<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
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() { 
    } 
} 

Dieses Problem ist für mich entscheidend. Siehe auch https://code.google.com/p/dart/issues/detail?id=14753&sort=-id&colspec=ID%20Type%20Status%20Priority%20Area%20Milestone%20Owner%20Summary

Antwort

5

Ich glaube, das Problem hier ist, dass ausstehende Änderungsbenachrichtigungen nicht verarbeitet werden, weil Ihr Code nicht in der Dirty-Check-Zone ausgeführt wird. Es gibt zwei Dinge, die Sie tun können, um dies zu beheben:

  • Anruf Observable.dirtyCheck() direkt nach dem Update auf caption; oder,
  • führen Sie den Code innerhalb der schmutzigen-Kontrollzone:
void main() { 
    var dirtyCheckingZone = initPolymer(); 
    dirtyCheckingZone.run(() { 
    ButtonElement btn = querySelector("#btn"); 
    btn.onMouseEnter.listen((e) { 
     MsgBoxElement elm = querySelector("#msg"); 
     elm.caption = "Caption 2"; 
    }); 
    }); 
} 

Diese Zone stellt sicher, dass nach jedem Rückruf oder Hörer ausgeführt wird, werden wir Observable.dirtyCheck für Sie anrufen. Dieser Ansatz ist etwas besser als der explizite Aufruf von dirtyCheck, da wir bei der Kompilierung für die Bereitstellung von "Dirty-Checking" zu "Explicit Notifications" wechseln. Die von initPolymer zurückgegebene Zone wird entsprechend geändert.

Eine separate Anmerkung: Das obige MsgBoxElement kann vereinfacht werden, wenn Sie die @published Annotation verwenden. Dies soll ausdrücken, dass eine Eigenschaft sowohl als beobachtbar als auch als Attribut Ihres Elements sichtbar ist.

import 'package:polymer/polymer.dart'; 

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

Dank! Der erste Ansatz funktioniert gut. Der zweite gibt null zurück (Methodenablauf). Deshalb habe ich eine Ausnahme bekommen. – Roman

+1

Das gleiche Problem gefunden .. Ich schlage vor, dass Sie nicht Ihr eigenes 'main()' verwenden und weiterhin 'polymer/init.dart' verwenden und dann' @CustomTag ('msg-box') 'und/oder' @ initMethod' verwenden Rufen Sie Ihre eigenen Methoden auf. Denken Sie daran, dass @ @ initMethod Aufrufe vor '@ CustomTag' ... – chameleon95

+0

Was sind die Nachteile von laufendem Code mit der Dirty-Check-Zone? Gibt es Alternativen dazu? Und noch philosophischer: Warum ist es nicht möglich, einen korrekten Konstruktor für eine Klasse zu erstellen, die von PolymerElement erbt? –

1

Basierend auf Ihren Informationen scheint es, dass das Modell aktualisiert wird, das DOM jedoch nicht aktualisiert wird, höchstwahrscheinlich weil ein beobachtbares Element nicht festgelegt ist. Versuchen Sie, die folgenden Anmerkungen zu Ihrem msg_box Dart-Code:

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() { 
    } 
} 

diese Breaking change announcement Siehe auf den Pfeil Mailinglisten über das @reflectable Attribut. Siehe auch this discussion bei der Einrichtung GETTER

+0

Leider funktioniert das nicht in der aktuellen Version von Dart-Polymer (0.8.10) – Roman