2015-03-26 2 views
2

Если пользователь нажимает на запись li, он вызывает действие useThisAddress, которое устанавливает isSelected в объекте address на true. Оттуда bind-attr заботится о настройке соответствующего класса (т. Е. `Border-black ').Как выделить выделенный адрес?

Это правильный путь? Или есть лучший подход?

Ниже код работает. Тем не менее, я немного не знаю, как установить isSelected на true на объект address, так как он не является реальным объектом в объектной модели address.

// Controller 
import Ember from 'ember'; 

export default Ember.Controller.extend({ 
    active: null, 

    actions: { 
    useThisAddress: function(address) { 
     address.set('isSelected', true); 
     var active = this.get('active'); 
     if (active) { 
     active.set('isSelected', false); 
     } 
     this.set('active', address); 
    } 
    } 
}) 

// Template 
<ul> 
    {{#each address in model}} 
    <li {{bind-attr class='address.isSelected:border-black'}} {{action 'useThisAddress' address}}> 
     Address: {{address.address1}} {{address.address2}}, {{address.city}}, {{address.postalCode}} 
    </li> 
    {{/each}} 
</ul> 

ответ

1

Я думаю, что ваша реакция на кишку правильная - вы не должны устанавливать свойства своих моделей, которые строго связаны с вашим пользовательским интерфейсом.

Компоненты являются строительными блоками в Ember для хранения состояния слоя UI. В Ember это довольно сложное время, потому что для этой цели также используются контроллеры, но они уже на пути. Скоро будут все компоненты.

Когда я сталкиваюсь с таким случаем, как ваш (список с выбранными предметами), я обычно делаю компонент list и компонент list-item. list знает, какой элемент выбран, и каждый list-item знает, выбрано ли оно. Для вашего простого случая одно из других решений может быть более прямолинейным, но я обычно нахожусь с этими списками, вы в конечном итоге захотите больше функциональности (привязка к выбранному элементу, более сложные шаблоны и т. Д.).

Так один подход может выглядеть следующим образом:

{{#address-list selected=selectedAddress as |list|}} 
    {{#each address in model}} 
    {{#address-list-item item=address list=list}} 
     <p>{{address.address1}}</p> 
    {{/address-list-item}} 
    {{/each}} 
{{/address-list}} 

используется блок Params (примечание: Ember 1,10 и выше), чтобы передать <address-list> в каждую <address-list-item>.Теперь ваш адрес элемент списка может сказать список новый адрес был выбран путем направления действия на него:

App.AddressListItemComponent = Ember.Component.extend({ 
    classNameBindings: ['active'], 

    active: function() { 
    return this.get('list.selected') === this.get('item'); 
    }.property('list.selected', 'item'), 

    click: function() { 
    this.get('list').send('select', this.get('item')); 
    } 
}); 

App.AddressListComponent = Ember.Component.extend({ 
    actions: { 
    select: function(item) { 
     this.set('selected', item); 
    } 
    } 
}); 

Это настраивает все привязки для вас, добавляет .active класса к каждым <address-list-item>, и позволяет вы привязываетесь к выбранному элементу <address-list> вне шаблона.

See a working JSBin here.

Теперь, ориентированный на list, как это использовать .send неудобно, и именно поэтому в ближайшее время мы сможем передать действия вниз в дочерние компоненты (проверить Road to Ember 2.0 руководства и поиск «улучшающих действия»). После того, как эта функциональность приземлится, вы сможете передать обработчик действий select с <address-list> непосредственно в каждый <address-list-item>. Но пока это один из способов, и это сделает рефакторинг довольно простым, когда эти изменения приземляются.

+0

Я не уверен, что все контроллеры выйдут наружу, просто ObjectController и ArrayController, которые обладают способностью проксирования (get ('foo') может получить доступ к this.foo или этому. model.foo). Исправьте меня, пожалуйста, если я ошибаюсь –

+2

не все контроллеры уходят, см. Раздел «Распределенные компоненты» [здесь] (https://github.com/emberjs/rfcs/pull/15) (и [маршрутизируемые компоненты RFC] (https://github.com/ef4/rfcs/blob/routeable-components/active/0000-routeable-components.md)) –

+0

убедитесь, что {{yield this}} в вашем - вот что делает блок param работает –

2

Как предложил here вы можете просто хранить отдельный список с выбранными элементами в контроллере.

0

Просто изучать Ember самостоятельно, но .... мой .02.

Подход к списку - это обязательный IMO.

Как вы это делаете, должно быть хорошо, если вы хотите, чтобы isSelected был квазиустойчивым. Он останется до тех пор, пока объект останется - даже, возможно, между изменением маршрута (в зависимости от вашей модели).

Если предполагается, что это будет более кратковременным. Выбросьте адрес в компонент и сохраните isChecked в контроллере компонента.

1

Когда вы говорите, что это не реальная собственность на объектной модели, я предполагаю, что вы просто подразумеваете, что она не сохраняется. Если это так, и нет другого использования для флага в любом месте, кроме текущего дисплея, долгосрочным решением будет использование компонента. См: http://jsbin.com/colacu/1

App = Ember.Application.create(); 

App.Router.map(function() { 
    // put your routes here 
}); 

App.IndexRoute = Ember.Route.extend({ 
    model: function() { 
    return [Ember.Object.create({ 
     address1: 'add1', 
     address2: 'add2', 
     city: 'Washington' 
    }), 
    Ember.Object.create({ 
     address1: 'add1 again', 
     address2: 'add2 again', 
     city: 'Seattle' 
    })]; 
    } 
}); 

App.IndexController = Ember.Controller.extend({ 
    active: null, 
    actions: { 
    useThisAddress: function(address) { 
     address.set('isSelected', true); 
     this.set('active', address); 
    } 
    } 
}); 

App.XAddressComponent = Ember.Component.extend({ 
    isSelected: false, 
    address: null, 
    tagName: 'li', 
    classNameBindings: ['isSelected'], 
    click: function() { 
    console.log('clicked!'); 
    this.sendAction('action', this); 
    } 
}); 

Шаблон:

<script type="text/x-handlebars" data-template-name="index"> 
    Selected: {{selected.value}} 
    <ul> 
    {{#each model as |item|}} 
     {{x-foo value=item action="select"}} 
    {{/each}} 
    </ul> 
    </script> 
    <script type="text/x-handlebars" data-template-name="components/x-foo"> 
    {{value}} 
    </script> 

Но что у вас есть должно быть прекрасно.

+0

Yeap, компоненты - путь. Но он не чувствует себя правильно, пытаясь установить состояние элемента адреса в модели данных ember. т.е. 'address.set ('isSelected', true);' –

Смежные вопросы