私のjavascriptオブジェクトは次のようになります。
$scope.display = {
current: {
key1: 'value1',
key2: ['a', 'b'],
key3: 'value2'
}
}
コード内のいくつかのイベントで、これらの値を以下のように未定義にリセットしたいと思います。
$scope.display = {
current: {
key1: undefined,
key2: [],
key3: undefined
}
}
Lodashのようなライブラリを使用していますが、これを実行する関数はありません。これを手動で行う方法は知っていますが、このタスクを実行するための「ベストプラクティス」の方法があるかどうか疑問に思いました。
オブジェクト構造を返すヘルパー関数を作成します。
_function getDisplayObject() {
return {
current: {
key1: undefined, // or you can omit undefined keys
key2: [],
key3: undefined
}
};
}
$scope.display = getDisplayObject();
_
したがって、後でデータをリセットする必要がある場合は、$scope.display = getDisplayObject();
を再度実行します。
これがlodashmapValues
関数を使った私の解決策です:
var $clearObject = function(value) {
if (_.isString(value)) {
return undefined
};
if (_.isArray(value)) {
return [];
};
};
var $scopeDisplay = {
current: {
key1: 'value1',
key2: ['a', 'b'],
key3: 'value2'
}
};
$scopeDisplay.current = _.mapValues($scopeDisplay.current, $clearObject);
console.log($scopeDisplay);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.min.js"></script>
このようにオブジェクトのプロパティをループします
for (var key in current){
if (current.hasOwnProperty(key)){
if (typeof current[key] === 'string'){
current[key] = undefined;
} else if (current[key] instanceof Array) {
current[key] = [];
} // else ??? Not sure how you want to handle other types
}
}
コメントで説明されているいくつかの潜在的な問題の対象となる配列チェック ここ
これはどうですか?
// If you just want to reset a simple object
let reset = (obj) => {
Object.keys(obj).map(key => {
if (obj[key] instanceof Array) obj[key] = []
else obj[key] = undefined
})
}
// If you want to reset a complex object
let recursiveReset = (obj) => {
Object.keys(obj).map(key => {
// Test if it's an Object
if (obj[key] === Object(obj[key])) {
recursiveReset(obj[key])
return
}
if (obj[key] instanceof Array) obj[key] = []
else obj[key] = undefined
})
}
// So you can simply use
reset($scope.display.current)
// or
recursiveReset($scope.display)
私のAngularコントローラーでは、次のことを行います。
$scope.user = {
firstname: "",
lastname: "",
displayname: "",
email: "",
password: "",
passwordConfirm: ""
};
// default state of the form
$scope.default = angular.copy($scope.user);
/**
* Resets the form to its default state
* @return {void}
*/
$scope.reset = function () {
$scope.user = angular.copy($scope.default);
}
最初はスコープが空なので、クローンを作成し、リセットが必要なときはいつでも関数を呼び出すだけです。ただし、プロジェクトの範囲を知らなければ、それを処理するための最良の方法を決定することは困難です。
私はAngularJSコントローラーで次のように行いました:
function item_object() {
var list_item = {
ID: '',
Title: '',
LastName: '',
Contact: '',
City: ''
};
return list_item;
}
//Define the object for the item
$scope.Item = item_object();
// Reset product details
$scope.clear = function () {
$scope.Item = item_object();
}
このようにして、空のオブジェクトまたはデフォルトのオブジェクトのコピーを保持しません。したがって、追加費用はかかりません。
組み込みの方法はありません。ループして、タイプに基づいてデフォルトを設定する必要があります。
var x = {
current: {
key1: 'value1',
key2: ['a', 'b'],
key3: 'value2'
}
};
_(x.current).forEach(
function(value, key, obj) {
var result = undefined;
if (_.isArray(value)) {
result = [];
}
obj[key] = result;
}
);
console.log(x);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
ネストされたオブジェクトがある場合の基本的な考え方
var x = {
current: {
key1: 'value1',
key2: ['a', 'b'],
key3: 'value2',
xxxx: {
keyx1: 'valuex1',
keyx2: ['xa', 'xb'],
keyx3: 'valuex2'
}
}
};
function resetObj (obj) {
_(obj).forEach(
function(value, key, objRef) {
var result = undefined;
if (_.isObject(value)) {
resetObj(objRef[key]);
} else {
if (_.isArray(value)) {
result = [];
}
objRef[key] = result;
}
}
);
}
resetObj(x)
console.log(x);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>
Jqueryを使用している場合は、使用しているように見えますが、次のことができます。
オブジェクトの空のテンプレートを事前に準備します。
var emptyTemplate = {
current: {
key1: undefined,
key2: [],
key3: undefined
}
}
次に実行します:
$scope.display = $.extend(true, {}, emptyTemplate);
自動化する場合は、データバインディングを定義します。
var defaults = {
String: undefined,
Array: [],
bool: false
}
次に、他の提案のように、オブジェクトをループします。
function resetObj (obj) {
_(obj).forEach(
function(value, key, objRef) {
if (_.isObject(value)) {
resetObj(objRef[key]);
} else {
var myvarType = typeOf value;
objRef[key] = defaults[myvarType];
}
}
);
}
この入れ子関数を他の回答からコピーして、2セントを追加しました。
これに対処する良い方法は、次のように、オブジェクトリテラルの代わりにクラスを使用することです。
class current {
constructor() {
this.key1 = undefined;
this.key2 = [];
this.key3 = undefined;
}
}
そして、すべての値をクリアしたいときはいつでも、次のように、このクラスの新しいインスタンスを作成できます。
$scope.display.current = new current();
function isObject (value) {
return value && typeof value === 'object' && value.constructor === Object;
}
const resetObj = (obj, resetVal) => {
if(!isObject(obj)) return;
for(let i in obj){
if(!obj.hasOwnProperty(i)) continue;
if(!isObject(obj[i])){
obj[i] = resetVal;
}else{
resetObj(obj[i], resetVal);
}
}
};