أفضل طريقة لتحديث/إضافة حالة عش أكسجين

أنا أستخدم رد فعل أصلي مع redux ، يمكن لواجهة المستخدم الخاصة بي زيادة قيمة attr مع التنسيق أدناه

{
  'page1': {
    'attrs': [
      {
        'attr1': {
          'value': 10
        }
      },
      {
        'attr2': {
          'value': 20
        }
      }
    ]
  }
}

ثلاث حالات عند إضافة attr:

  1. إذا كان attr ، على سبيل المثال ، "attr2" موجودة بالفعل ، وزيادة قيمتها
  2. إذا كان attr ، على سبيل المثال ، "attr3" غير موجود ، أضف attr جديدًا
  3. إذا كانت الصفحة ، على سبيل المثال ، 'page2' غير موجود ، أضف صفحة جديدة ثم attr
  4. جديد

سيكون الكثير من المنطق من أجل التحقق من الصفوف وتكرار القائمة. أي اختزال أو أفضل طريقة لذلك؟

0

2 إجابة

لا أعتقد أنه سيكون هناك طريقة بسيطة للتعامل مع هذا فقط باستخدام Ramda. إن عدسات رمضة محدودة إلى حد ما ، مستعارة من اللغات حيث تكون هياكل البيانات أكثر صرامة ، وبالتالي أقل سهولة في العمل مع الهياكل الجزئية. قد ترغب في الاطلاع على مكتبة lenses lenses ، والتي تم تصميمها حول هذه الأنواع من المشاكل.


تحديث

في الفكر الثاني ، هناك شيء يمكن قوله عن استخدام عدسات Ramda ، حتى لو كان بناء العدسات فظيعًا جدًا. أنا متأكد من أن هناك طريقة أفضل لكتابة منشئ العدسة هذا ، ولكن الحل أدناه ممكن.

بمجرد إنشاء العدسة ، يمكنك استخدامها مع view في Ramda ، set ، أو (مع وظيفة مثل inc ) ، over . هذا يجعل طريقة متسقة للتركيز على سمة معينة لصفحة معينة.

كما قلت ، هذا المنشئ عدسة سيئة للغاية ، والتعامل مع جميع الطرق الممكنة يمكن أن تسوء الأمور. لكن الرمز الذي يستخدمه معقول جدا.

<div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false"> <div class="snippet-code">

const { lens, find, has, findIndex, assocPath, تحديث, 
        append, assoc, view, set, over, inc} = R

const pageAttrValueLens = (pageName, attrName) => lens(
  (pages) => (find(
    has(attrName), 
    (pages[pageName] || {attrs: []}).attrs
  ) || {[attrName]: {value: 0}})[attrName].value,
  (val, pages) => {
    const page = pages[pageName] || {attrs: []}
    const attrIdx = findIndex(has(attrName), page.attrs)
    const idx = attrIdx === -1 ? page.attrs.length : attrIdx
    const attr = page.attrs[idx] || {[attrName]: {value: 0}}
    const newAttr = assocPath([attrName, 'value'], val, attr)
    const attrs = idx < page.attrs.length 
                ? تحديث(idx, newAttr, page.attrs)
                : append(newAttr, page.attrs)
    const newPage = assoc('attrs', attrs, page)
    return assoc(pageName, newPage, pages)
  }
)

const pages = {
  'page1': {
    'attrs': [
      {'attr1': {'value': 10}},
      {'attr2': {'value': 20}}
    ]
  }
}

console.log(view(pageAttrValueLens('page1', 'attr2'), pages)) //=> 20
console.log(view(pageAttrValueLens('page1', 'attr3'), pages)) //=> 0
console.log(view(pageAttrValueLens('page2', 'attr1'), pages)) //=> 0

console.log(set(pageAttrValueLens('page1', 'attr2'), 42, pages))
  //=> {"page1":{"attrs":[{"attr1":{"value":10}},{"attr2":{"value":42}}]}}
console.log(set(pageAttrValueLens('page1', 'attr3'), 42, pages))
  //=> {"page1":{"attrs":[{"attr1":{"value":10}},{"attr2":{"value":20}},{"attr3":{"value":42}}]}}
console.log(set(pageAttrValueLens('page2', 'attr1'), 42, pages))
  //=> {"page1":{"attrs":[{"attr1":{"value":10}},{"attr2":{"value":20}}]},"page2":{"attrs":[{"attr1":{"value":42}}]}}


console.log(over(pageAttrValueLens('page1', 'attr2'), inc, pages))
  //=> {"page1":{"attrs":[{"attr1":{"value":10}},{"attr2":{"value":21}}]}}
console.log(over(pageAttrValueLens('page1', 'attr3'), inc, pages))
  //=> {"page1":{"attrs":[{"attr1":{"value":10}},{"attr2":{"value":20}},{"attr3":{"value":1}}]}}
console.log(over(pageAttrValueLens('page2', 'attr1'), inc, pages))
  //=> {"page1":{"attrs":[{"attr1":{"value":10}},{"attr2":{"value":20}}]},"page2":{"attrs":[{"attr1":{"value":1}}]}}
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
</div> </div>
0
وأضاف

أعتقد أنه يمكنك تحسين بنية البيانات الخاصة بك قليلاً لجعل التحديث أسهل. في حالتك ليست هناك حاجة ل "attrs" لتكون صفيف. يمكنك فعل شيء كهذا:

{
    "page1": {
      "attrs": {
        "attr1": 10,
        "attr2": 20,
        "attr3": 30
      }
    }
}

لذلك يجب أن يكون الاختبار إذا كانت السمة موجودة بهذه السهولة

if(page1.attrs[atrrName]) {...}
0
وأضاف