2013-06-11 5 views
0

Я пытаюсь написать представление Ember, состоящее из трех состояний. В частности, кнопка отправки, которая переходит с «Отправить» на «Сохранение ...» на «Готово!» Есть много способов достичь этой цели, но мне было интересно, что «лучшая практика» будет с точки зрения Эмберга, чтобы достичь этого, не написав дрянной код.Шаблон ручек с несколькими состояниями

В настоящее время у меня есть следующий код:

UiControls.SubmitButton = Ember.View.extend({ 

    template: function() { 
    var template = '{{#if view.isNotStarted}}Submit{{/if}}'; 
    template += '{{#if view.isStarted}} <i class="icon-spinner icon-spin"></i>Saving...{{/if}}'; 
    template += '{{#if view.isFinished}} <i class="icon-check-sign"></i>Finished!{{/if}}' 
    return Ember.Handlebars.compile(template); 
    }.property(), 

    isNotStarted: true, 
    isStarted: null, 
    isFinished: null, 

    classNames: ['btn', 'btn-green'], 

    isDisabled: false, 

    click: function(){ 
    if (!this.get('disabled')){ 
     this.set('isNotStarted', false); 
     this.set('isStarted', true); 
     this.set('isFinished', false); 
     this.timer(); 
    } 
    }, 

    /* Simulates a server call */ 
    timer: function(){ 
    (function(self){ 
     setTimeout(function(){ 
     self.set('isStarted', false); 
     self.set('isFinished', true); 
     }, 500); 
    })(this); 
    } 
}); 

Для меня это действительно некрасиво - мы устанавливаем индивидуальные логические значения, основанные от событий для того, чтобы работать с намеренно ограниченным условным синтаксисом рулей.

Что я хочу - это конструкция ручек, которая принимает что-то вроде свойства Ember StateManager (невозможно с синтаксисом Handlebars). Или, по крайней мере, я хочу изменить свой шаблон на основе вычисленного свойства из StateManager (опять же, это невозможно). Поэтому мой вопрос заключается в том, есть ли лучший способ написать вышеприведенный код, чтобы предотвратить перекодирование операций с копированием кода вручную через множество небольших логических манипуляций с флагом?

ответ

2

Для меня это действительно уродливо - мы устанавливаем отдельные булевы значения, основанные на событиях, чтобы работать с целенаправленно ограниченным условным синтаксисом руля.

Полностью согласен, это признак того, что необходим какой-то рефакторинг.

Что я хочу - это конструкция ручек, которая принимает нечто вроде свойства Ember StateManager (невозможно с синтаксисом Handlebars).

Возможно, если вы напишете специальный помощник руля, но, честно говоря, я бы не рекомендовал этот подход.

Или, по крайней мере, я хочу, чтобы изменить мой шаблон, основанный прочь вычисленного собственности от StateManager (опять же, не возможно)

Почему нет? Угадав, что вы имеете в виду, даже если у вас есть это свойство, невозможно изменить шаблон без всех логических элементов.

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

Да. Причина handlebars имеет это ограничение, чтобы предотвратить сложность и логику от того, чтобы быть частью ваших шаблонов. Например, в любое время, когда вам нужно показать, как 1-из-3 версии, основанные на некотором значении. Такая логика принадлежит слою представления или контроллера.

Так, глядя на ваш пример, есть два аспекта шаблона, которые необходимо изменить

  • текст: Должен быть либо «Сохранить», «Сохранение ...» или «Готово!"
  • iconClassNames: Либо пустой "значок-вертушка значок-спиновые" или "значок-чек-знак"

Имея это в виду, мы можем упростить шаблон быть:

<i {{bindAttr class="view.iconClassNames"></i>{{view.text}} 

и добавить свойства к представлению

UiControls.SubmitButton = Ember.View.extend({ 
    template: Ember.Handlebars.compile('<i {{bindAttr class="view.iconClassNames"></i>{{view.text}}'), 
    classNames: ['btn', 'btn-green'], 
    isDisabled: false, 
    text: "Submitted", 
    iconClassNames: "", 
    click: function(){ 
    if (!this.get('disabled')){ 
     this.set('text', 'Saving...'); 
     this.set('iconClassNames', 'icon-spinner icon-spin'); 
     this.timer(); 
    } 
    }, 

    /* Simulates a server call */ 
    timer: function(){ 
    (function(self){ 
     setTimeout(function(){ 
     this.set('text', 'Finished!'); 
     this.set('iconClassNames', 'icon-check-sign'); 
     }, 500); 
    })(this); 
    } 
}); 

Это работает для моделирования, но не идеально. на самом деле вы хотите текст и iconCla ssNames должно быть bound в stateManager. Это означает изменение значений text и iconClassNames. В идеале они будут вычисляться на основе базового состояния объекта модели, и click() будет определен на контроллере, но для моделирования это будет примерно так:

UiControls.SubmitButton = Ember.View.extend({ 
    template: Ember.Handlebars.compile('<i {{bindAttr class="view.iconClassNames"></i>{{view.text}}'), 
    classNames: ['btn', 'btn-green'], 
    isDisabled: false, 
    state: 'new', 
    text: function() { 
    //return appropriate button text based on state 
    }.property('state'), 
    iconClassNames: function() { 
    //calculate text based on state 
    }.property('state'), 

    /* Simulates a server call */ 
    click: function(){ 
    if (!this.get('disabled')){ 
     this.set('state', 'saving'); 
     this.timer(); 
    } 
    }, 

    /* Simulates a server call */ 
    timer: function(){ 
    (function(self){ 
     setTimeout(function(){ 
     self.set('state', 'finished'); 
     }, 500); 
    })(this); 
    } 
}); 
Смежные вопросы