Обновление значения ключа JSON из массива по индексу - PullRequest
0 голосов
/ 12 сентября 2018

Я использую Angular javascript для выполнения задачи, в которой мне нужно обновить значение ключа JSON из массива по щелчку.

У меня есть JSON структура, подобная этой: -

$scope.jsonObj = {
    "stylesheet": {
        "attribute-set": [{
                "attribute": {
                    "_name": "text-align",
                    "__prefix": "xsl",
                    "__text": "center"
                },
                "_name": "__frontmatter",
                "__prefix": "xsl"
            },
            {
                "attribute": [{
                        "_name": "space-before",
                        "__prefix": "xsl",
                        "__text": "80mm"
                    },
                    {
                        "_name": "line-height",
                        "__prefix": "xsl",
                        "__text": "140%"
                    }
                ],
                "_name": "__frontmatter__title",
                "_use-attribute-sets": "common.title",
                "__prefix": "xsl"
            }
        ],
        "_version": "2.0",
        "__prefix": "xsl"
    }
};

У меня есть массив $scope.textvalue=["center", "80mm","150%"].Поэтому здесь я хочу обновить значение ключа __text JSON в соответствии с индексом.Означает, что я хочу выдвинуть детали массива в соответствии с индексом __text в JSON и массиве.

Я делаю это при нажатии кнопки в controller .

$scope.save = function(index) {
    $scope.textvalue[index];
    console.log($scope.textvalue);
    $scope.objIndex = $scope.jsonObj.findIndex((obj => obj.__text));
    console.log("Before update: ", $scope.jsonObj[$scope.objIndex]);
    $scope.jsonObj[$scope.objIndex].__text = ? ? ? ;
    console.log("After update: ", $scope.jsonObj[$scope.objIndex]);
}

Я $scope.jsonObj[$scope.objIndex].__text = ???;поскольку я не знаю, что здесь делать, и у меня есть ошибка, поскольку $ scope.jsonObj.findIndex не является функцией

Предложите мне какой-нибудь способ обновить мое значение JSON.

Ответы [ 3 ]

0 голосов
/ 12 сентября 2018

Основная проблема заключается в том, что attribute может быть либо литералом объекта, либо массивом литералов объекта.Вот функция, которая проходит через jsonObj, сравнивая __text и возвращая ссылку на рассматриваемый атрибут.Если ничего не найдено, вместо него добавляется новый атрибут:

function getAttribute(__text) {
  var attributes = $scope.jsonObj['stylesheet']['attribute-set']; 
  for (var i=0, l=attributes.length; i<l; i++) {
    var attribute = attributes[i].attribute;
    if (attribute.length) {  //array of attributes
       for (attr in attribute) {
         if (attribute[attr].__text == __text) return attribute[attr]
       }
    } else {  //attribute literal
      if (attribute.__text == __text) return attribute
    } 
  }
  var index = attributes.push({  
    attribute: { __text: __text } 
  });
  return attributes[i].attribute
}

пример:

var center = getAttribute('center');
center.NEW_VALUE = 'TEST';

var new_attr = getAttribute('new_attr');
new_attr.__prefix = 'SOMETHING';  
0 голосов
/ 12 сентября 2018

Вы можете сделать это, перебирая массив $scope.jsonObj.stylesheet["attribute-set"], используя Array.forEach() метод и обновляя соответствующие свойства "__text" соответственно для каждого attribute объекта / массива .

  • Я использовал Array#isArray() метод , чтобы проверить, является ли повторяемое свойство attribute array или object.
  • Я скопировал массив $scope.textvalue в arr и использовал Array#shift() метод для получения соответствующего значения из массива arr в каждой итерации.

Вот как должен быть ваш код:

const arr = $scope.textvalue.slice();
$scope.jsonObj.stylesheet["attribute-set"].forEach(function(a) {
  if (Array.isArray(a.attribute)) {
    a.attribute.forEach(att => att["__text"] = arr.shift());
  } else {
    a.attribute["__text"] = arr.shift();
  }
});

Демо-версия:

$scope= {};
$scope.jsonObj = {
  "stylesheet": {
    "attribute-set": [{
        "attribute": {
          "_name": "text-align",
          "__prefix": "xsl",
          "__text": "center"
        },
        "_name": "__frontmatter",
        "__prefix": "xsl"
      },
      {
        "attribute": [{
            "_name": "space-before",
            "__prefix": "xsl",
            "__text": "80mm"
          },
          {
            "_name": "line-height",
            "__prefix": "xsl",
            "__text": "140%"
          }
        ],
        "_name": "__frontmatter__title",
        "_use-attribute-sets": "common.title",
        "__prefix": "xsl"
      }
    ],
    "_version": "2.0",
    "__prefix": "xsl"
  }
};

$scope.textvalue = ["center", "80mm", "150%"];
const arr = $scope.textvalue.slice();

$scope.jsonObj.stylesheet["attribute-set"].forEach(function(a) {
  if (Array.isArray(a.attribute)) {
    a.attribute.forEach(att => att["__text"] = arr.shift());
  } else {
    a.attribute["__text"] = arr.shift();
  }
});
console.log($scope.jsonObj);
0 голосов
/ 12 сентября 2018

Я бы сделал это так.Я создал такую ​​функцию, как вы (за исключением того, что сейчас ее нет в AngularJS, но вы можете очень легко это сделать).

Вы передаете индекс функции, он будет перебирать вхождения __text и выяснять, куда поместить значение.

Вот рабочий фрагмент: (см. 150% в последнем / третьем __text значении, когда я передаю соответствующий индекс)

let jsonObj = {
  "stylesheet": {
    "attribute-set": [{
        "attribute": {
          "_name": "text-align",
          "__prefix": "xsl",
          "__text": "center"
        },
        "_name": "__frontmatter",
        "__prefix": "xsl"
      },
      {
        "attribute": [{
            "_name": "space-before",
            "__prefix": "xsl",
            "__text": "80mm"
          },
          {
            "_name": "line-height",
            "__prefix": "xsl",
            "__text": "140%"
          }
        ],
        "_name": "__frontmatter__title",
        "_use-attribute-sets": "common.title",
        "__prefix": "xsl"
      }
    ],
    "_version": "2.0",
    "__prefix": "xsl"
  }
};

let textvalue = ["center", "80mm", "150%"];

let textvalueIndex = 0;

function save(index) {
  let updated = jsonObj.stylesheet['attribute-set'].reduce(function(agg, obj) {
    if (Array.isArray(obj.attribute)) {
      for (let i = 0; i < obj.attribute.length; i++) {
        if (textvalueIndex === index) {
          obj.attribute[i].__text = textvalue[textvalueIndex];
        }
        textvalueIndex++;
      }
    } else {
      if (textvalueIndex === index) {
        obj.attribute.__text = textvalue[textvalueIndex];
      }
      textvalueIndex++;
    }
    agg.push(obj);
    return agg;
  }, [])

  console.log(updated)
}

save(2) // third item in textvalue array will be saved on the third occurance of __text
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...