Backbone: أضف طريقة "إعادة تعيين" إلى Backbone.Model

تم إنشاؤها على ٣١ يوليو ٢٠١٤  ·  22تعليقات  ·  مصدر: jashkenas/backbone

كنت بحاجة إلى تحديث بعض بيانات النموذج الواردة من الخادم. يوجد حاليًا خياران: الاتصال بـ Model.set ، أو قم بتعيين Model.attributes مباشرةً. لم أرغب في تسجيل التغييرات ، لكنني أيضًا لا يمكنني استخدام silent لأنني كنت بحاجة إلى تحديث العروض المعنية. لذلك ، كتبت رقعة قرد:

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

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

هل تساءلت عن سبب عدم امتلاك Backbone.Model طريقة إعادة تعيين مثل Backbone.Collection ؟

question

التعليق الأكثر فائدة

thesmart ، لا يقوم Model # set

يجب أن يكون شرطًا لإعطاء سبب عند إغلاق قضية. أود معرفة سبب إغلاق @ akre54 لهذا. تعد نماذج العمود الفقري بدائية بشكل متعمد وغير معلن عنها ، ومع ذلك ، فإن عدم وجود نموذج # إعادة تعيين يعبر عن رأي حول كيفية استخدام النماذج. من http://backbonejs.org/#Getting -started

من الناحية الفلسفية ، يعد Backbone محاولة لاكتشاف الحد الأدنى من بنية البيانات (النماذج والمجموعات) وأساسيات واجهة المستخدم (المشاهدات وعناوين URL) التي تكون مفيدة بشكل عام عند إنشاء تطبيقات الويب باستخدام JavaScript.

ال 22 كومينتر

إعادة التعيين هي فتحة هروب ، تتيح لك إجراء تصيير فعال بكميات كبيرة بسهولة عندما تعلم أنك بحاجة إليه.

لحالتك ، فقط استخدم set .

هل يمكنك التعيين دون إجراء تغييرات السمات متسخة؟

في 1 آب (أغسطس) 2014 ، الساعة 7:28 صباحًا ، كتب جيريمي أشكيناس [email protected] :

إعادة التعيين هي فتحة هروب ، تتيح لك إجراء تصيير فعال بكميات كبيرة بسهولة عندما تعلم أنك بحاجة إليه.

لحالتك ، فقط استخدم مجموعة.

-
قم بالرد على هذا البريد الإلكتروني مباشرةً أو قم بعرضه على GitHub.

استدعاء Model.clear() قبل Model.set({}) سيعمل في حالتك؟ بهذه الطريقة لن تقوم بتوسيع السمات الحالية ، بل سيتم استبدالها. يدعم Model.clear() أيضًا الخيار الصامت إذا كنت لا تريد تشغيل حدثين "تغيير" على النموذج.

أوافق على أن هذه الطريقة مفقودة. فكرت أيضًا في استخدام model.clear() و model.set() بالتزامن. ثم واجهت المشكلة ، حيث قمت بتشغيل الحدث change مرتين الآن.
استخدام الخيار silent عند استدعاء model.clear() ليس خيارًا ، لأنني أريد أيضًا تشغيل حدث change ، عندما يتم إلغاء تعيين خاصية.

ستأخذ طريقة model.reset() تجزئة سمات جديدة وتعبئ هذه التجزئة بقيم undefined لمفاتيح السمات القديمة غير الموجودة في تجزئة السمة الجديدة.

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);
};

تضمين التغريدة

ماذا عن:

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

لا ، هذا لا يساعد. تخيل أن لديك مفتاحًا foo في تجزئة السمات الحالية للنموذج ، وهو غير موجود في التجزئة الجديدة attrs التي تمررها إلى model.reset() . عندما أستمع إلى حدث change:foo ، فلن يتم تشغيله بالقيمة الجديدة undefined ، لأننا استخدمنا model.unset() في الوضع الصامت.

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/

رائع ، فهمت ما تعنيه. من المحتمل أن أختار استخدام this.unset(key, options) على تجاوز هذه السمات بشكل صريح ، ولكن هذا مجرد مسألة تبديل attrs[key] = void 0; : panda_face:

عفوا عن أي جهل أظهِره ، لأنني ما زلت جديدًا نسبيًا على backbone.js ، لكن السلوك الذي تتم مناقشته يبدو وكأنه Model.fetch . الوصف يقول:

يعيد تعيين حالة النموذج من الخادم

يبدو كما لو أن أحداث change ما زالت قيد التشغيل ولكن لا تجعل النموذج "متسخًا". هل هناك سبب لعدم إمكانية اتباع هذا الأسلوب عندما تبحث عن إعادة تعيين السمات بناءً على استجابة الخادم؟ أتخيل أن الموقف الوحيد الذي قد يحدث هذا هو عندما يتغير نموذج كأثر جانبي لعملية أخرى ، ولكن بشكل عام تعتبر هذه الآثار الجانبية برمجة سيئة ويجب تجنبها إن أمكن. إذا كان لا يمكن تجنب التأثير الجانبي ، فربما يكون من المنطقي إرسال علامة استجابة "تحديث نموذج XYZ" بدلاً من سمات النموذج الجديد وتشغيل fetch كلما رأيت مثل هذه الاستجابة.

مرة أخرى ، عفوا عن أي جهل أعرضه في هذا التعليق.

@ kolorahl ،

ما يريد OP تحقيقه هو مسح سمات النموذج الحالي وتمرير JSON جديد والذي يصبح السمات الجديدة للنموذج. بهذه الطريقة ، لا نريد حقًا ضرب الواجهة الخلفية إذا كان لدينا بالفعل JSON.

أتفق بطريقة ما مع @ lupugabriel1 مع أسلوبه الواضح +. لكنني أعتقد أن هذه إحدى الوظائف التي يجب أخذها في الاعتبار. شيء مثل العمود الفقري. إعادة تعيين المجموعة #

سبب احتياجي لهذا هو أن العالم يتغير. يفترض العمود الفقري أن Model # fetch () XHR هي الطريقة الأساسية لتحميل البيانات من الخادم ، ولكننا نقوم بالكثير من الأشياء باستخدام مآخذ الويب. عندما يتم دفع البيانات إلى العميل ، يكون الأمر زائدًا عن استدعاء .fetch ونحتاج إلى طريقة مناسبة لتحميل البيانات جنبًا إلى جنب مع الاستمرار في تشغيل خطاف الحدث.

لماذا لا تستخدم #set ؟

jridgewell لأن #set ستجعل السمات متسخة. لنجرب استخدام المجموعة ونرى ما سيحدث:

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'}
{foo: "what?"}

النتيجة المرجوة:

{foo: 'bar'}
false

التعيين مناسب عندما تتغير الحالة خارج المزامنة مع الخادم ، ولكن إعادة تعيين Model # مطلوب لأنه لا توجد طريقة لوضع علامة على الحالة كمزامنة مع الخادم.

انتهى بي الأمر بكتابة رقعة قرد مختلفة لهذه الميزة:

/**
 * 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

ربما يحتاج هذا إلى إلغاء تعيين العناصر المفقودة أيضًا. لست متأكدًا مما إذا كان Model # set (attributes) يفعل ذلك.

كما أشار lennerd ، فإن استدعاء clear() متبوعًا بـ set() ليس خيارًا جيدًا ، لأنه

1) إطلاق حدثين change و
2) إذا كنت تستخدم silent:true في المكالمة clear ، فلن تحصل على أحداث التغيير على السمات التي لم يتم ضبطها.

collection.reset() بديهي للغاية وأعتقد أن Model يمكن أن يستفيد حقًا من طريقة معادلة. أجد نفسي أحاول استخدام model.reset(attrs) طوال الوقت ، دائمًا ما أشعر بخيبة أمل عندما لا يكون هناك. :(

ذهبت إلى الأمام وخلق القليل من التمديد لإضافة العمل reset طريقة لBackbone.Model: العمود الفقري الموديل-إعادة تعيين

موافق - سيكون من المفيد أن يكون لديك أصلاً. كنت بحاجة إلى إعادة تعيين السمات فقط دون تشويه سمة "id" ، كما كان يفعل clear (). ها هو جوهر ذلك .

thesmart ، لا يقوم Model # set

يجب أن يكون شرطًا لإعطاء سبب عند إغلاق قضية. أود معرفة سبب إغلاق @ akre54 لهذا. تعد نماذج العمود الفقري بدائية بشكل متعمد وغير معلن عنها ، ومع ذلك ، فإن عدم وجود نموذج # إعادة تعيين يعبر عن رأي حول كيفية استخدام النماذج. من http://backbonejs.org/#Getting -started

من الناحية الفلسفية ، يعد Backbone محاولة لاكتشاف الحد الأدنى من بنية البيانات (النماذج والمجموعات) وأساسيات واجهة المستخدم (المشاهدات وعناوين URL) التي تكون مفيدة بشكل عام عند إنشاء تطبيقات الويب باستخدام JavaScript.

بقدر ما أستطيع أن أقول ، فإن نموذج بيانات Backbone غير متوافق مع REST
لأنه لا توجد طريقة لنمذجة الحالة بأمان على العميل بعد أ
تم بناء النموذج. بناء نموذج جديد هو السبيل الوحيد للحصول عليه
حالة جديدة دون إعادة تعيين.

في يوم الثلاثاء 5 يوليو 2016 ، كتب pgifford [email protected] :

thesmart https://github.com/thesmart ، لا يتم إلغاء تعيين Model # set في عداد المفقودين
السمات وهذا هو السبب في أنني أعتقد أن إعادة تعيين الموديل # ضرورية

يجب أن يكون شرطًا لإعطاء سبب عند إغلاق قضية. هوية شخصية
أحب أن أعرف لماذا @ akre54 https://github.com/akre54 أغلق هذا.
تعد نماذج العمود الفقري بدائية بشكل متعمد وغير معلن عنها ، ومع ذلك ، فإن
يعبر عدم وجود Model # reset عن رأي حول كيفية استخدام النماذج. من عند
http://backbonejs.org/#Getting -started

من الناحية الفلسفية ، يعد العمود الفقري محاولة لاكتشاف الحد الأدنى من مجموعة
هيكلة البيانات (النماذج والمجموعات) وواجهة المستخدم (العروض و
URLs) العناصر الأساسية التي تكون مفيدة بشكل عام عند إنشاء تطبيقات الويب
مع JavaScript.

-
أنت تتلقى هذا لأنه تم ذكرك.
قم بالرد على هذا البريد الإلكتروني مباشرة ، وقم بعرضه على GitHub
https://github.com/jashkenas/backbone/issues/3253#issuecomment -230586424 ،
أو كتم الخيط
https://github.com/notifications/unsubscribe/AARJLQ8-BGeV0X_owHVpyPQAdeiMweNMks5qSriDgaJpZM4CTBHH
.

كنت بحاجة إلى نموذج reset وذهبت إلى الأمام وصنعه في _روح_العمود الفقري. أستخدم هذا في الامتداد الشخصي الخاص بي من العمود الفقري.

إنه أفضل من .clear بسيط متبوعًا بـ .set لأنه يدمج الإعدادات الافتراضية مرة أخرى في النموذج ، مما يسمح لأي سمات تم تمريرها لتجاوزها مثل عند التهيئة.

/**
 * 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);
},

يؤدي إلى أحداث التغيير ( change و change:attribute ) بالإضافة إلى الحدث model:reset المخصص إذا لم يكن silent: true . يمكن تخصيصه بسهولة لتشغيل الحدث model:reset فقط ولكني أعتقد أنه يجب دائمًا تشغيل أحداث التغيير عند إعادة تعيين النموذج.

لقد قمت بتعديل حل lennerd https://github.com/jashkenas/backbone/issues/3253#issuecomment -58789524 قليلاً.

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;
};
هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات