2014-10-26 3 views
0

Предположим, что есть приложение, написанное в файле response.js. Он извлекает один json через rest api и передает некоторые свойства дочерним компонентам.Как бороться с отсутствующими полями в response.js

Что такое надлежащий способ обработки потенциально отсутствующих атрибутов json и других? Я, вероятно, следует проверить в каждом компоненте, если реквизит есть, и заполнить состояние с правильной структурой, но заполнены с пустыми данными, что-то вроде этого:

var SomeComponent = React.createClass({ 
getInitialState: function() { 
    return { 
    someNestedStructure: { 
     foo: { 
     bar: null, 
     baz: null 
     }, 
     morenested: { 
     something: '', 
     andEvenMoreNested: { 
      somethingb: '' 
     } 
     }, 
     somedata: { 
     id: null 
     }, 
     somedataaa: { 
     } 
    } 
    } 
}, 
componentDidMount: function() { 
    //call rest api and set new state depending on what is inside json 
    //check every required field to pass to children compoents 
}, 
render: function() { 
    return (
    <div> 
     <ComponentUsingNEsteStructure data={this.state.someNestedStructure.moreNested}/> 
     <ComponentThatNeedsEverythign data={this.state.someNestedStructure} /> 
     <SomeOtherComponent some={this.sate.somedataaa} /> 
    </div> 
); 
} 
}); 

Но я предполагаю, что это произведет много связанных JSon структур внутри кода и много ifs.

Спасибо за помощь!

ответ

2

Это не относится к Реагированию. То, что вы хотите, глубоко расширяется. Эта информация доступна на НПМ, deep-extend

использования, как это:

var defaultsForThing = { 
    foo: '', 
    bar: { 
    baz: true, 
    quux: null 
    } 
}; 

// make a defaulting function 
var defaultThing = deepExtend.bind(null, defaultsForThing); 

// fetch some data which might be missing fields 
$.getJSON('/api', function(data){ 
    var fixed = defaultThing(data); 
    doSomethingWith(fixed); 
}); 

Вот функция deepExtend (но предпочитают linked to module)

var deepExtend = module.exports = function (/*obj_1, [obj_2], [obj_N]*/) { 
    if (arguments.length < 1 || typeof arguments[0] !== 'object') { 
     return false; 
    } 

    if (arguments.length < 2) return arguments[0]; 

    var target = arguments[0]; 

    // convert arguments to array and cut off target object 
    var args = Array.prototype.slice.call(arguments, 1); 

    var key, val, src, clone, tmpBuf; 

    args.forEach(function (obj) { 
     if (typeof obj !== 'object') return; 

     for (key in obj) { 
      if (! (key in obj)) continue; 

      src = target[key]; 
      val = obj[key]; 

      if (val === target) continue; 

      if (typeof val !== 'object' || val === null) { 
       target[key] = val; 
       continue; 
      } else if (val instanceof Buffer) { 
       tmpBuf = new Buffer(val.length); 
       val.copy(tmpBuf); 
       target[key] = tmpBuf; 
       continue; 
      } else if (val instanceof Date) { 
       target[key] = new Date(val.getTime()); 
       continue; 
      } else if (val instanceof RegExp) { 
       target[key] = new RegExp(val); 
       continue; 
      } 

      if (typeof src !== 'object' || src === null) { 
       clone = (Array.isArray(val)) ? [] : {}; 
       target[key] = deepExtend(clone, val); 
       continue; 
      } 

      if (Array.isArray(val)) { 
       clone = (Array.isArray(src)) ? src : []; 
      } else { 
       clone = (!Array.isArray(src)) ? src : {}; 
      } 

      target[key] = deepExtend(clone, val); 
     } 
    }); 

    return target; 
} 

Одна вещь, которую я мог бы изменить в этой функции что он не удовлетворяет этому случаю:

var defaults = { 
    a: [{b: 0, c: 0}] 
}; 

var obj = { 
    a: [{b: 1}, {b: 2}, {c: 3}] 
}; 

deepExtend(defaults, obj); 

Чтобы исправить ответы json, вы бы хотели получить следующее: однако это не является технически глубоким дефолтом (это принуждение схемы).

{ 
    a: [{b: 1, c: 0}, {b: 2, c: 0}, {c: 3, b: 0}] 
} 
+0

ну, я думаю, вот как я собираюсь это сделать, спасибо! – user3924850

0

Вы можете избежать большого, вложенного объекта на верхнем уровне, используя getDefaultProps назначить по умолчанию для реквизита каждого компонента для удовлетворения недостающих значений. Вы можете перенести доступ REST API к родительскому объекту и передать результаты дочерним элементам через свои реквизиты (вам нужно будет использовать состояние родителя как триггер для повторной рендеринга дочернего элемента при получении ответа AJAX).

Смежные вопросы