2011-12-16 20 views
7

入力選択から値をコントローラ内の属性「selectedValue」にバインドしようとしています。値のフォームの入力選択をコントローラの属性にバインドする方法

これは私がオプションに値を追加する方法は考えている。これは、index.htmlをこの

<select id="ember180" class="ember-view"> 
    <option id="ember192" class="ember-view"> 
    <script id="metamorph-0-start" type="text/x-placeholder"></script> 
    a 
    <script id="metamorph-0-end" type="text/x-placeholder"></script> 
    </option> 
    <option id="ember196" class="ember-view"> 
    <script id="metamorph-1-start" type="text/x-placeholder"></script> 
    b 
    <script id="metamorph-1-end" type="text/x-placeholder"></script> 
    </option> 
    <option id="ember200" class="ember-view"> 
    <script id="metamorph-2-start" type="text/x-placeholder"></script> 
    c 
    <script id="metamorph-2-end" type="text/x-placeholder"></script> 
    </option> 
</select> 

よう

{{#collection 
    contentBinding="Todos.todosController" 
    tagName="select" 
    itemClassBinding="content.isDone"}} 
    {{content.title}} 
{{/collection}} 

出力表情でapp.js

Food = Ember.Application.create(); 

Food.appsController = Ember.Object.create({ 
    selectedValue: "" 
}); 

Food.Todo = Ember.Object.extend({ 
    title: null, 
    value: null 
}); 

Food.FoodController = Ember.ArrayProxy.create({ 
    content: [] 
}); 

Food.FoodController.pushObject(Food.Todo.create({title:"a", value:"1"})); 
Food.FoodController.pushObject(Food.Todo.create({title:"b", value:"2"})); 
Food.FoodController.pushObject(Food.Todo.create({title:"c", value:"3"})); 

で、選択した値をコントローラにバインドする方法。 これはEmberjsで可能ですか? ...

をEmber.Viewが私のために動作しますが、私はよりよい解決策があると思いますカスタムを使用して

答えて

7

Emberには選択ビューが組み込まれました。

最新のEmberで見つけることができます。jsがここに建てる:http://cloud.github.com/downloads/emberjs/ember.js/ember-latest.js

は、ここで使用例です:あなたのテンプレートは次のようになり

var App = Ember.Application.create(); 

App.Person = Ember.Object.extend({ 
    id: null, 
    firstName: null, 
    lastName: null, 

    fullName: function() { 
     return this.get('firstName') + " " + this.get('lastName'); 
    }.property('firstName', 'lastName').cacheable() 
}); 

App.selectedPersonController = Ember.Object.create({ 
    person: null 
}); 

App.peopleController = Ember.ArrayController.create({ 
    content: [ 
     App.Person.create({id: 1, firstName: 'Yehuda', lastName: 'Katz'}), 
     App.Person.create({id: 2, firstName: 'Tom', lastName: 'Dale'}), 
     App.Person.create({id: 3, firstName: 'Peter', lastName: 'Wagenet'}), 
     App.Person.create({id: 4, firstName: 'Erik', lastName: 'Bryn'}) 
    ] 
}); 

{{view Ember.Select 
     contentBinding="App.peopleController" 
     selectionBinding="App.selectedPersonController.person" 
     optionLabelPath="content.fullName" 
     optionValuePath="content.id"}} 

ここでも、ここjsFiddle例です:http://jsfiddle.net/ebryn/zgLCr/

+0

はEmberコアにこのビューを追加する必要があります:-) – Bank

+1

Emberにすぐに含まれる改良版があります:https://github.com/emberjs/ember.js/pull/424 – ebryn

+0

btw [Ember.Select api](http://emberjs.com/api/classes/Ember.Select.html) –

4

は、実施例を参照してください。このフィドルあるhttp://jsfiddle.net/pangratz/hcxrJ/

ハンドルバー:

{{#view Food.SelectView contentBinding="Food.foodController" 
    valueBinding="Food.appsController.selectedValue"}} 
    <select> 
     {{#each content}} 
      <option {{bindAttr value="value"}} >{{title}}</option> 
     {{/each}} 
    </select> 
{{/view}} 

アプリ.js:

Food = Ember.Application.create(); 

Food.SelectView = Ember.View.extend({ 
    value: null, 

    valueChanged: function(){ 
     this.$('select').val(this.get('value')); 
    }.observes('value'), 

    didInsertElement: function(){ 
     var self = this; 
     this.$('select').change(function(){ 
      var val = $('select option:selected').val(); 
      self.set('value', val); 
     }); 
    } 
}); 

Food.appsController = Ember.Object.create({ 
    selectedValue: "" 
}); 

Food.Todo = Ember.Object.extend({ 
    title: null, 
    value: null 
}); 

Food.foodController = Ember.ArrayProxy.create({ 
    content: [] 
}); 

Food.foodController.pushObject(Food.Todo.create({title:"a", value:"1"})); 
Food.foodController.pushObject(Food.Todo.create({title:"b", value:"2"})); 
Food.foodController.pushObject(Food.Todo.create({title:"c", value:"3"})); 
+0

このソリューションは適しています私には複数の理由があります: a)Ember.Selectビューは、選択された値としてコンテンツ配列内のオブジェクト全体を返します。実際の選択値を取り戻すことに興味がありました。 b)私はこの実装で作業しているものがはるかに高速です:ラベルと値にバインドする必要はありませんが、変更しません(上記のビュークラス拡張でvalueChangedメソッドを削除しました。 最終的な発言:選択変更ハンドラメソッドには小さなエラーが含まれています(セレクタが複数ある場合):$( 'オプションを選択する...は自己にする必要があります$(' select options ... – Visionscaper

5

@pangrantzの解決策から飛び降りるこのFidd le example(http://jsfiddle.net/bsyjr/)では、いくつかの改善点が示されています。ハンドルバーコードは、tagNameを使用することでよりクリーンです。 tagNameが "select"に設定されている場合、子ビューは自動的に "オプション"要素になります。理由を理解するには、Ember.CollectionView.CONTAINER_MAPのhttps://github.com/emberjs/ember.js/blob/master/packages/ember-views/lib/views/collection_view.jsを参照してください。 Javascript側では、itemViewClassを指定することによって、value属性をoption要素に追加できます。

<script type="text/x-handlebars" > 
    {{#collection Food.SelectView tagName="select" contentBinding="Food.foodController" 
     valueBinding="Food.appsController.selectedValue"}} 
     {{content.title}} 
    {{/collection}} 

    selected: {{view Ember.TextField valueBinding="Food.appsController.selectedValue"}}{{Food.appsController.selectedValue}} 
</script> 

Food = Ember.Application.create(); 

Food.SelectView = Ember.CollectionView.extend({ 
    value: null, 
    itemViewClass: SC.View.extend({ 
     attributeBindings:['value'], 
     valueBinding: 'content.value' 
    }), 

    valueChanged: function(){ 
     this.$().val(this.get('value')); 
    }.observes('value'), 

    didInsertElement: function(){ 
     var self = this; 
     this.$().change(function(){ 
      var val = $('select option:selected').val(); 
      self.set('value', val); 
     }); 
    } 
}); 

Food.appsController = Ember.Object.create({ 
    selectedValue: "" 
}); 

Food.Todo = Ember.Object.extend({ 
    title: null, 
    value: null 
}); 

Food.foodController = Ember.ArrayProxy.create({ 
    content: [] 
}); 

Food.foodController.pushObject(Food.Todo.create({title:"a", value:"1"})); 
Food.foodController.pushObject(Food.Todo.create({title:"b", value:"2"})); 
Food.foodController.pushObject(Food.Todo.create({title:"c", value:"3"})); 

ありエンバーのイベントフレームワークを使用していないイベント処理、改善の余地はまだある、そしてそれは多くの意味がIMO以来、ハンドルバーを活用していないカスタム書かれSelectViewを使用するようになるだろう、この場合、ハンドルバーがどのくらいの価値を追加するのかは疑わしいです。

+3

@pangratzが行ったように '{{#each}} 'を使って同じ結果をより明確に得ることができるので、' {{#collection}}'ヘルパーは非推奨です –

+0

さらに明確にするために、しかし、私は最初に '{{#each}} 'を使ってみるつもりですが、あなたが望む結果を得ることができない場合は、' {{#collection}} 'を計画していますより多くのcをカバーする '{{#each}}'をさらに改善するases。 –

1

これは他の人には使いやすいのかどうかは分かりませんが、私はここの答えに基づいて同様のことをしてきましたが、このコンテキストでも動作するSelectViewを作っています。これは '変更'にバインドし、現在選択されているビューを処理し、その内容で何かを行います。

Food.SelectView = Ember.CollectionView.extend({ 
    change: function(e) { 
    var selected = this.$().find(":selected").index(); 
    var content = this.get('childViews')[selected].content; 
    // Do something with the result 
    Food.appsController.set('selectedValue', content.title); 
    } 
}); 

あなたがオブジェクトではなく、選択の指標の周囲を通過することができますこの方法です。

関連する問題