2013-11-04 73 views
5

以下代碼不起作用。也許我做錯事。請糾正我的代碼:飛鏢聚合物:不能從事件處理程序中設置屬性

  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'!!! 
    });` 
} 
  • msg_box.html
  • <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

    回答

    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(); 
    } 
    
    +0

    謝謝!第一種方法很好。第二個返回null(方法運行)。因此我得到了一個例外。 – Roman

    +1

    找到同樣的問題..我建議避免使用自己的main(),並繼續使用'polymer/init.dart',然後使用@CustomTag('msg-box')'和/或'@ initMethod'調用你自己的方法..記住'@ initMethod'在'@ CustomTag'之前調用... – chameleon95

    +0

    運行代碼的髒檢區域有什麼缺點?有替代品嗎?更多的哲學:爲什麼不可能爲從PolymerElement繼承的類創建適當的構造函數? –

    1

    根據您的信息,看起來該模型正在更新,但DOM未更新,很可能是因爲未設置可觀察元素。嘗試添加以下注釋到您的msg_box鏢代碼:

    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在鏢郵件列表關於@reflectable屬性。另請參閱this discussion設置@observable獲取者

    +0

    不幸的是,這並不適用於當前版本的飛鏢聚合物(0.8.10) – Roman