2012-07-29 5 views
5

私はこの質問に答えるためにしようとしていた。emberjs: add routes after app initialize()Ember.Object.reopen()で遊んでいるのはなぜですか?

私はそれがどのように動作するかを理解するために、)Ember.Object.reopen(と遊び始め、おそらく前の質問に答えるの方法を見つけます。

私は少し戸惑いを感じており、このコードの動作を理解していない:

jsfiddle:http://jsfiddle.net/Sly7/FpJwT/

<script type="text/x-handlebars"> 
    <div>{{App.myObj.value}}</div> 
    <div>{{App.myObj2.value}}</div> 
    <div>{{App.myObj3.value}}</div> 
</script> 
App = Em.Application.create({}); 

App.MyObject = Em.Object.extend({value: 'initial'}); 

App.set('myObj', App.MyObject.create()); 

Em.run.later(function(){ 
    App.get('myObj').reopen({ 
    value: "reopenOnInstance"   
    }); // the template is not updated, 'initial' is still diplayed, but 
    console.log(App.get('myObj').get('value')); // print 'reopenOnInstance' 

    App.MyObject.reopen({ 
    value: "reopenOnClass"  
    }); 
    App.set('myObj2',App.MyObject.create()); // the template is updated and 
    console.log(App.get('myObj2').get('value')); //print 'reopenOnClass' 

    App.myObj3 = App.MyObject.create(); // the template is not updated but 
    console.log(App.myObj3.get('value')); // print 'reopenOnClass' 

    Em.run.later(function(){ 
    App.get('myObj').set('value', "setWithSetter"); // the template is updated and 
    console.log(App.get('myObj').get('value')); // print 'setWithSetter' 

    App.get('myObj2').set('value', "setWithSetter"); // the template is updated and 
    console.log(App.get('myObj2').get('value')); // print 'setWithSetter' 

    App.myObj3.set('value', "setWithSetter"); // the template is not updated but 
    console.log(App.myObj3.get('value')); // print 'setWithSetter' 

    }, 2000); 
},2000); 

誰かが何が起こっているかを説明することができた場合は、特に理由テンプレートは時々更新されず、ときどき更新され、あるクラスでreopenを呼び出して呼び出す場合と、インスタンスで呼び出す場合の違いは何ですか?

答えて

5

100%ではありませんが、私はあなたの質問にお答えします。

まず、 "myObj3"を見てください。 ember getter/setterメソッドは、テンプレート内の更新をトリガーします(プロパティ/オブザーバが発生したことをすべて知る内部イベントを発生させます)。手で値を設定するだけで値は更新されますが、これらのイベントは発生せず、UIでは何も変更されません。変更可能なリストを使用する場合は、UIが更新されることを確認するためにpushObjectを使用するようなものです。

ここであなたの "再オープン"を見てみましょう。このクラスを再度開くと、基本クラスの予想どおりに動作します。インスタンスを再度開くと、実際にはミックスインが作成され、オブジェクトの上にシムが表示されます。これは、あなたが "get" emberを実行したときにmixinの値を返すために&オブジェクトを反復処理することを意味します。それはmixinを見つけ、オブジェクトの前の値を取得します。実際にはメソッドを "戻り値" foo '+ this._super() "と置き換えることができます。インスタンスには' foo initial '(オブジェクトにはタマネギのようなレイヤーがあると思っています)となります。オブジェクトの上にミックスインのグループがある場合は、何かを直接設定しても(しかし "完璧に動く")、正しい値を見つけるのは難しいでしょう。これは、直接参照の代わりに常に "set"を使うべきであるという一般的なルールにつながります。

サイドノート:「get」の代わりに「getPath」を呼び出して、相対パスまたは絶対パスを使用できます。 App.getPath( 'myObj2.value')など、コードの管理が簡単になります。 "setPath"にも行きます。

最後に値を変更したので、最後の値が表示されますが、emberが "myObj3"オブジェクトでsetを呼び出したことがないため、ユーザーIDが更新されることはありません。

EDIT:インスタンスの再オープンがオブジェクトのマージダウンを行うように(そのキーがすでに存在する場合)、emberの最新バージョンでは見えます。ミックスインは、新しいコンテンツを追加する場合にのみラップされます。

+0

すべて意味があります。大変感謝してくれてありがとう。ですから、私がここでやっているようにインスタンスを再オープンしても、App.get( 'myObj')と同じ動作をします。value = 'reopenOnInstance'' right? 私はgetPath、メソッドを知っていましたが、最新のemberではgetに同じ動作があり、 'obj.get( 'otherObj.someProperty')'を実行できます。 –

+0

編集を参照してください。これは、あなたが正しいことを意味します。値を直接設定することは、インスタンスの再オープンのようになります。しかし、あなたが何かその値(UIなど)にバインドしている場合、Emberは「set」が使用されなかったためにエラーをスローします([phiddler](http://jsfiddle.net/scispear/n5B5d/)エラー)。 – SciSpear

+0

もう一度編集していただきありがとうございます。私は解明すべきことがもうないので、答えは完了したと思います。 –

関連する問題