Backbone: Tambahkan metode "reset" ke Backbone.Model

Dibuat pada 31 Jul 2014  ·  22Komentar  ·  Sumber: jashkenas/backbone

Saya perlu memperbarui beberapa data Model yang masuk dari server. Saat ini, ada dua opsi: panggil Model.set , atau setel Model.attributes secara langsung. Saya tidak ingin perubahan direkam, tetapi saya juga tidak dapat menggunakan silent karena saya memerlukan masing-masing tampilan untuk diperbarui. Jadi, saya menulis tambalan monyet:

Backbone.Model.prototype.reset = (attributes, options) ->
    attrs = attributes || {};
    if options.parse
      attrs = this.parse(attrs, options) || {}

    @set(attrs, options);
    <strong i="9">@changed</strong> = {};

Bertanya-tanya mengapa Backbone.Model tidak memiliki metode reset seperti Backbone.Collection ?

question

Komentar yang paling membantu

@thesmart , Model # set tidak

Ini harus menjadi persyaratan untuk memberikan alasan saat menutup sebuah masalah. Saya ingin tahu mengapa @ akre54 menutup ini. Model backbone sengaja dibuat primitif dan unopinionated, namun, kurangnya model # reset mengungkapkan pendapat tentang bagaimana model digunakan. Dari http://backbonejs.org/#Getting -mulai

Secara filosofis, Backbone adalah upaya untuk menemukan set minimal penataan data (model dan koleksi) dan primitif antarmuka pengguna (tampilan dan URL) yang umumnya berguna saat membangun aplikasi web dengan JavaScript.

Semua 22 komentar

Reset adalah jalan keluar, yang memungkinkan Anda melakukan rendering yang efisien secara massal dengan mudah saat Anda tahu bahwa Anda membutuhkannya.

Untuk kasus Anda, cukup gunakan set .

Dapatkah Anda mengatur tanpa membuat perubahan atribut menjadi kotor?

Pada 1 Agustus 2014, pukul 7:28 pagi, Jeremy Ashkenas [email protected] menulis:

Reset adalah jalan keluar, yang memungkinkan Anda melakukan rendering yang efisien secara massal dengan mudah saat Anda tahu bahwa Anda membutuhkannya.

Untuk kasus Anda, cukup gunakan set.

-
Balas email ini secara langsung atau lihat di GitHub.

Menelepon Model.clear() sebelum Model.set({}) akan berfungsi dalam kasus Anda? Dengan cara ini Anda tidak akan memperluas atribut saat ini, melainkan akan diganti. Model.clear() juga mendukung opsi diam jika Anda tidak ingin memicu dua peristiwa "perubahan" pada model.

Saya setuju bahwa metode ini hilang. Saya juga berpikir untuk menggunakan model.clear() dan model.set() secara bersamaan. Kemudian saya menemukan masalah, bahwa saya memicu peristiwa change dua kali sekarang.
Menggunakan opsi silent saat memanggil model.clear() bukanlah suatu opsi, karena saya juga ingin mengaktifkan peristiwa change , ketika properti tidak disetel.

Metode model.reset() akan mengambil hash atribut baru dan mengisi hash ini dengan nilai undefined untuk kunci atribut lama yang tidak ada dalam hash atribut baru.

Model.prototype.reset = function(attrs, options) {
    for (var key in this.attributes) {
        if (key in attrs) continue;
        attrs[key] = void 0;
    }

    return this.set(attrs, options);
};

@tokopedia

Bagaimana dengan:

Model.prototype.reset = function(attrs, options) {
    for (var key in this.attributes) {
        this.unset(key, {silent:true});
    }
    return this.set(attrs, options);
};

Tidak, ini tidak membantu. Bayangkan Anda memiliki kunci foo dalam hash atribut model saat ini, yang tidak ada dalam hash attrs Anda berikan ke model.reset() . Ketika saya mendengarkan acara change:foo , itu tidak akan dipicu dengan nilai baru undefined , karena kami menggunakan model.unset() dalam mode diam.

Backbone.Model.prototype.reset = function(attrs, options) {
    for (var key in this.attributes) {
        this.unset(key, {silent:true});
    }
    return this.set(attrs, options);
};

var bar = new Backbone.Model();

bar.on('change', function(model) {
    console.log('The model bar has been changed.');
});

bar.on('change:foo', function(model, foo) {
    console.log('Foo has been changed to: ' + foo);
});

bar.set(foo, 'test');
// => The model bar has been changed.
// => Foo has been changed to: test

bar.reset({ foo2: 'test2' });
// => The model bar has been changed.
// Foo was resetted but no change event has been triggered.

http://jsfiddle.net/lennerd/3s1Ltwgu/

Keren, saya mengerti maksud Anda. Saya mungkin memilih untuk menggunakan this.unset(key, options) untuk menimpa this.attributes secara eksplisit, tapi itu hanya masalah menukar attrs[key] = void 0; : panda_face:

Maafkan ketidaktahuan yang saya tunjukkan, karena saya masih relatif baru di backbone.js, tetapi perilaku yang dibahas terdengar seperti Model.fetch . Deskripsi mengatakan:

Mereset status model dari server

Sepertinya peristiwa change masih terpicu tetapi tidak membuat model "kotor". Adakah alasan mengapa pendekatan ini tidak dapat dilakukan saat Anda ingin menyetel ulang atribut berdasarkan respons server? Saya membayangkan satu-satunya situasi seperti ini yang mungkin terjadi adalah ketika model berubah sebagai efek samping dari operasi lain, tetapi umumnya efek samping seperti itu dianggap pemrograman yang buruk dan harus dihindari jika memungkinkan. Jika efek samping tidak dapat dihindari, mungkin lebih masuk akal untuk mengirimkan tanda tanggapan "model pembaruan XYZ" daripada atribut model baru dan memicu fetch setiap kali Anda melihat tanggapan seperti itu.

Sekali lagi, maafkan ketidaktahuan yang saya tunjukkan dalam komentar ini.

@bayu_joo ,

Apa yang OP ingin capai adalah menghapus atribut model saat ini dan meneruskan JSON baru yang menjadi atribut baru model. Dengan cara ini, kami tidak benar-benar ingin mencapai backend jika sudah memiliki JSON.

Saya setuju dengan @ lupugabriel1 dengan metode clear + set-nya. Tapi menurut saya ini adalah salah satu fungsi yang perlu diperhatikan. Sesuatu seperti Backbone.Collection # reset

Alasan saya membutuhkan ini adalah karena dunia sedang berubah. Backbone mengasumsikan Model # fetch () XHR adalah metode utama untuk memuat data dari server, tetapi kami melakukan lebih banyak hal menggunakan websockets. Ketika data didorong ke klien, itu berlebihan untuk memanggil .fetch dan kita membutuhkan cara yang layak untuk memuat data secara samping dan masih mendapatkan hook peristiwa untuk dipicu.

Mengapa Anda tidak menggunakan #set ?

@jridgewell karena #set akan membuat atribut kotor. Mari coba gunakan set dan lihat apa yang terjadi:

function callback(data_from_server) {
  console.info(data_from_server);
  m = new Backbone.Model(data_from_server);
  m.set('foo', 'what?', {silent: true});
  console.info(m.changedAttributes())
}

Hasil sebenarnya:

{foo: 'bar'}
{foo: "what?"}

Hasil yang diinginkan:

{foo: 'bar'}
false

Set baik-baik saja ketika status berubah tidak sinkron dengan server, tetapi Setel ulang model diperlukan karena tidak ada cara untuk menandai status sebagai sinkron dengan server.

Saya akhirnya menulis tambalan monyet yang berbeda untuk fitur ini:

/**
 * Allow for side-loading data from the server, calling the sync event afterwards.
 * <strong i="6">@param</strong> attributes
 * <strong i="7">@param</strong> options
 */
Backbone.Model.prototype.sync_set = function(attributes, options) {
  var attrs = attributes || {};
  if (options.parse) {
    attrs = this.parse(attrs, options) || {}
  }

  this.set(attrs, options);
  this.changed = {};
  this.trigger('sync', this, attributes, options);
  return this;
}
function callback(data_from_server) {
  console.info(data_from_server);
  m = new Backbone.Model(data_from_server);
  m.set('foo', 'what?', {silent: true});
  console.info(m.changedAttributes())
}
{foo: 'bar'}
false

Ini mungkin juga perlu menghapus item yang hilang. Tidak yakin apakah Model # set (atribut) melakukan itu.

Seperti yang dikatakan @lennerd , memanggil clear() diikuti oleh set() bukanlah pilihan yang baik, karena itu

1) Mengaktifkan dua acara change dan
2) Jika Anda menggunakan silent:true pada panggilan clear , Anda tidak mendapatkan peristiwa perubahan pada atribut yang tidak disetel.

collection.reset() sangat intuitif dan saya pikir Model benar-benar bisa mendapatkan keuntungan dari metode yang setara. Saya menemukan diri saya mencoba menggunakan model.reset(attrs) sepanjang waktu, selalu kecewa jika tidak ada. :(

Saya melanjutkan dan membuat sedikit ekstensi untuk menambahkan metode reset berfungsi ke Backbone.Model: Backbone-Model-Reset

Setuju - akan berguna untuk memiliki secara native. Saya hanya perlu menyetel ulang atribut tanpa merusak atribut 'id', seperti yang dilakukan clear (). Inilah intinya .

@thesmart , Model # set tidak

Ini harus menjadi persyaratan untuk memberikan alasan saat menutup sebuah masalah. Saya ingin tahu mengapa @ akre54 menutup ini. Model backbone sengaja dibuat primitif dan unopinionated, namun, kurangnya model # reset mengungkapkan pendapat tentang bagaimana model digunakan. Dari http://backbonejs.org/#Getting -mulai

Secara filosofis, Backbone adalah upaya untuk menemukan set minimal penataan data (model dan koleksi) dan primitif antarmuka pengguna (tampilan dan URL) yang umumnya berguna saat membangun aplikasi web dengan JavaScript.

Sejauh yang saya tahu, model data Backbone tidak kompatibel dengan REST
karena tidak ada cara untuk membuat model status server dengan aman pada klien setelah file
model telah dibangun. Membangun model baru adalah satu-satunya cara untuk mendapatkannya
keadaan segar tanpa reset.

Pada hari Selasa, 5 Juli 2016, pgifford [email protected] menulis:

@thesmart https://github.com/thesmart , Model # set tidak hilang disetel
atribut itulah sebabnya saya pikir Model # reset diperlukan.

Ini harus menjadi persyaratan untuk memberikan alasan saat menutup sebuah masalah. Indo
ingin tahu kenapa @ akre54 https://github.com/akre54 menutup ini.
Model tulang punggung sengaja primitif dan unopinionated, namun
kurangnya Model # reset mengungkapkan pendapat tentang bagaimana model digunakan. Dari
http://backbonejs.org/#Getting -mulai

Secara filosofis, Backbone adalah upaya untuk menemukan himpunan minimal
penataan data (model dan koleksi) dan antarmuka pengguna (tampilan dan
URL) primitif yang umumnya berguna saat membangun aplikasi web
dengan JavaScript.

-
Anda menerima ini karena Anda disebutkan.
Balas email ini secara langsung, lihat di GitHub
https://github.com/jashkenas/backbone/issues/3253#issuecomment -230586424,
atau nonaktifkan utasnya
https://github.com/notifications/unsubscribe/AARJLQ8-BGeV0X_owHVpyPQAdeiMweNMks5qSriDgaJpZM4CTBHH
.

Saya membutuhkan model reset dan melanjutkan dan membuatnya di _spirit_ dari Backbone. Saya menggunakan ini di ekstensi pribadi saya di Backbone.

Ini lebih baik daripada .clear diikuti oleh .set karena ini menggabungkan default kembali ke model, membiarkan atribut yang dilewatkan untuk menimpanya seperti pada inisialisasi.

/**
 * Clears the model's attributes and sets the default attributes.
 * <strong i="10">@param</strong> {Object} attributes to overwrite defaults
 * <strong i="11">@param</strong> {Object} options  to pass with the "set" call.
 * <strong i="12">@return</strong> {Backbone.Model}  this object, to chain function calls.
 */
reset: function(attributes, options) {
    options = _.extend({ reset: true }, options);

    // ensure default params
    var defaults = _.result(this, 'defaults'),
        attrs = _.defaults(_.extend({}, defaults, attributes || {}), defaults);

    // apply
    this._reset(attrs, options);

    // triggers a custom event, namespaced to model in order
    // to avoid collision with collection's native reset event
    // when listening to a collection.
    if (!options.silent) this.trigger('model:reset', this, options);

    return this;
},

/**
 * Private method to help wrap reset with a custom behavior in child
 * classes.
 * <strong i="13">@param</strong>  {Object} attributes to overwrite defaults
 * <strong i="14">@param</strong>  {Object} options  to pass with the "set" call.
 */
_reset: function(attrs, options) {
    this.clear({ silent: true }).set(attrs, options);
},

Ini memicu peristiwa perubahan ( change dan change:attribute ) selain peristiwa khusus model:reset jika bukan silent: true . Ini dapat dengan mudah disesuaikan untuk memicu hanya peristiwa model:reset tetapi saya pikir bahwa peristiwa perubahan harus selalu dipicu saat menyetel ulang model.

saya telah mengubah solusi lennerd https://github.com/jashkenas/backbone/issues/3253#issuecomment -58789524 sedikit.

Backbone.Model.prototype.reset = function(attrs, options) {
    var missing = {};
    for (var key in this.attributes) {
        if (key in attrs) continue;
        attrs[key] = undefined;
        missing[key] = true;
    }
    // trigger all change events at the same time
    this.set(attrs, options);
    // remove missing attributes completely
    for (var key in missing) {
        // no silent option here in case  attributes changed again meanwhile (edge case)
        this.unset(key)
    }
    return this;
};
Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

etler picture etler  ·  13Komentar

g00fy- picture g00fy-  ·  9Komentar

omenking picture omenking  ·  10Komentar

rafde picture rafde  ·  9Komentar

jamiebuilds picture jamiebuilds  ·  12Komentar