SORU
18 ŞUBAT 2014, Salı


Facebook kullanarak kodu yeniden Tepki için vs bileşenleri mixins

Tepki Omurga bir projede Facebook kullanmaya başladım ve şu ana kadar gerçekten iyi gidiyor.
Ancak, bazı çoğaltılması kodumu Tepki sürünen fark ettim.

Örneğin,Form gibi çeşitli aletler varBirleşik Devletleri gibi INITIAL, SENDING SENT. Bir düğmeye basıldığında, form doğrulanmış olması gerekir, bir istekte bulundu ve daha sonra devlet güncellenir. Devlet elbette this.state, alan değerleri ile birlikte Tepki içinde tutulur.

Eğer bu Omurga manzarası olsaydı, bir temel sınıf FormView ama denilen çıkarılan olurdubenim izlenimim o ne destekliyor ne de Tepki paylaşma mantığı sınıflara destekler(eğer yanılıyorsam beni düzeltin).

Tepki yeniden kod için iki yaklaşım gördüm:

Mixins ve kaplar Tepki miras için tercih ettiği doğru mu? Bu kasıtlı bir tasarım kararı mı?Bir kendisine dahil ederse kullanmak daha mantıklı ya da benim için kapsayıcı bir bileşen “örnek ikinci paragraf? widget şeklinde olurdu

Here's a gist with FeedbackWidget and JoinWidget in their current state. Benzer bir yapı, beginSend benzer yöntem ve bazı doğrulama desteği olması lazım (henüz değil).

CEVAP
18 ŞUBAT 2014, Salı


Güncelleme: bu cevap eskidir. Eğer yapabiliyorsanız, mixins uzak dur. Seni uyarmıştım!
Mixins Are Dead. Long Live Composition

İlk başta, bunun için bileşenleri kullanın ve FormWidget InputWidget ayıklamak için çalıştı. Ancak, yarım inputler ve onların devlet tarafından oluşturulan üzerinde daha iyi bir kontrol istedim çünkü bu yaklaşım terk ettim.

Bana en çok yardım eden iki makale:

Ben sadece iki (farklı) mixins yazmak için gerekli olan bu ortaya çıktı: ValidationMixin FormMixin.
Ayırdım.

ValidationMixin

Doğrulama kendisine dahil ederse, ekler kolaylık devletin bazı özellikleri üzerinde doğrulayıcı fonksiyonları çalıştırmak ve depolamak için yöntemler “hata ... ilgili alanları vurgulamak için” state.errors bir dizi özellikleri.

Kaynak (gist)

define(function () {

  'use strict';

  var _ = require('underscore');

  var ValidationMixin = {
    getInitialState: function () {
      return {
        errors: []
      };
    },

    componentWillMount: function () {
      this.assertValidatorsDefined();
    },

    assertValidatorsDefined: function () {
      if (!this.validators) {
        throw new Error('ValidatorMixin requires this.validators to be defined on the component.');
      }

      _.each(_.keys(this.validators), function (key) {
        var validator = this.validators[key];

        if (!_.has(this.state, key)) {
          throw new Error('Key "'   key   '" is defined in this.validators but not present in initial state.');
        }

        if (!_.isFunction(validator)) {
          throw new Error('Validator for key "'   key   '" is not a function.');
        }
      }, this);
    },

    hasError: function (key) {
      return _.contains(this.state.errors, key);
    },

    resetError: function (key) {
      this.setState({
        'errors': _.without(this.state.errors, key)
      });
    },

    validate: function () {
      var errors = _.filter(_.keys(this.validators), function (key) {
        var validator = this.validators[key],
            value = this.state[key];

        return !validator(value);
      }, this);

      this.setState({
        'errors': errors
      });

      return _.isEmpty(errors);
    }
  };

  return ValidationMixin;

});

Kullanımı

ValidationMixin üç yöntem vardır: validate, hasError resetError.
Sınıf validators nesne propTypes benzer tanımlamak için bekliyor:

var JoinWidget = React.createClass({
  mixins: [React.addons.LinkedStateMixin, ValidationMixin, FormMixin],

  validators: {
    email: Misc.isValidEmail,
    name: function (name) {
      return name.length > 0;
    }
  },

  // ...

});

Kullanıcı gönderim düğmeye bastığında, validate diyorum. 27* *bir ara her onaylayıcı çalıştırın ve doğrulama başarısız oldu özellikleri anahtarları içeren bir dizi ile this.state.errors dolduracaktır.

render benim yöntem hasError alanlar için doğru CSS sınıf oluşturmak için kullanın. Kullanıcı koyar alanı içinde odak, resetError gelecek kadar hata vurgulamayı kaldırmak için diyorum validate Ara.

renderInput: function (key, options) {
  var classSet = {
    'Form-control': true,
    'Form-control--error': this.hasError(key)
  };

  return (
    <input key={key}
           type={options.type}
           placeholder={options.placeholder}
           className={React.addons.classSet(classSet)}
           valueLink={this.linkState(key)}
           onFocus={_.partial(this.resetError, key)} />
  );
}

FormMixin

Form kendisine dahil ederse, devlet (,, teslim gönderme düzenlenebilir) şeklinde işler. İstek gönderilirken devre dışı girişler ve düğmeler için kullanabilirsiniz ve görünümü gönderildiğinde buna uygun olarak güncellemek için.

Kaynak (gist)

define(function () {

  'use strict';

  var _ = require('underscore');

  var EDITABLE_STATE = 'editable',
      SUBMITTING_STATE = 'submitting',
      SUBMITTED_STATE = 'submitted';

  var FormMixin = {
    getInitialState: function () {
      return {
        formState: EDITABLE_STATE
      };
    },

    componentDidMount: function () {
      if (!_.isFunction(this.sendRequest)) {
        throw new Error('To use FormMixin, you must implement sendRequest.');
      }
    },

    getFormState: function () {
      return this.state.formState;
    },

    setFormState: function (formState) {
      this.setState({
        formState: formState
      });
    },

    getFormError: function () {
      return this.state.formError;
    },

    setFormError: function (formError) {
      this.setState({
        formError: formError
      });
    },

    isFormEditable: function () {
      return this.getFormState() === EDITABLE_STATE;
    },

    isFormSubmitting: function () {
      return this.getFormState() === SUBMITTING_STATE;
    },

    isFormSubmitted: function () {
      return this.getFormState() === SUBMITTED_STATE;
    },

    submitForm: function () {
      if (!this.isFormEditable()) {
        throw new Error('Form can only be submitted when in editable state.');
      }

      this.setFormState(SUBMITTING_STATE);
      this.setFormError(undefined);

      this.sendRequest()
        .bind(this)
        .then(function () {
          this.setFormState(SUBMITTED_STATE);
        })
        .catch(function (err) {
          this.setFormState(EDITABLE_STATE);
          this.setFormError(err);
        })
        .done();
    }
  };

  return FormMixin;

});

Kullanımı

Bileşen bir yöntem sağlamak için umuyor: Mavi kuş söz dönmelidir olan sendRequest,. (Önemsiz gibi Q veya başka bir söz kütüphanesi ile çalışmak için değiştirmek için.)

isFormEditable, isFormSubmitting isFormSubmitted gibi yöntemler kolaylık sağlar. Ayrıca istek başlaması için bir yöntem sağlar: submitForm. Form düğme' onClick işleyicisi. dan arayabilirsiniz

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Call Me Howard

    Call Me Howa

    18 AĞUSTOS 2012
  • CMTelly

    CMTelly

    2 Mayıs 2007
  • GUN-TIME with Brandon

    GUN-TIME wit

    3 ŞUBAT 2009