2015-09-15 3 views
1

Я запускаю приложение Angular, которое извлекает его данные из службы Web API. API возвращает объекты как JSON, а служба Angular (через $ http.get()) возвращает их в контроллер как массив объектов. Довольно нормальный материал.Добавление свойства в объект Angular

Что бы я хотел сделать, это добавить свойство для каждого из возвращаемых объектов, называемых «Selected». Это свойство предназначено исключительно для целей GUI (это объект, выбранный или нет в пользовательском интерфейсе), и его не нужно сохранять каким-либо образом. Я решил, что проще всего было бы перебрать возвращенный массив объектов и просто добавить его. Так что мой код выглядит следующим образом:

function getData() { 
    myService.getData() 
     .then(function(data) { 
      $scope.myData = data.results; 
      // Add a "Selected" property to each object 
      $.each($scope.myData, function(item) { 
       item.Selected = false; 
      }); 
} 

Когда он попадает в линию, которая говорит, «item.Selected = ложь» это бросить сообщение об ошибке, говоря: «Невозможно присвоить свойство только для чтения Selected».

Непонятно, почему «Selected» доступен только для чтения? Я не знал, может ли Angular обрабатывать некоторые фанковые объекты при чтении данных? Что я здесь делаю неправильно? Или я должен подойти к этому совершенно по-другому?

Примечание (я бы хотел, чтобы не сделать выбранную часть исходного объекта, поскольку она не является репрезентативной для чего-либо связанного с этим объектом).

+0

У вас есть верные данные? При использовании 'strict mode' * (который, я надеюсь, вы есть) *, попытка присвоить свойство примитивному значению (например, строка или логическое значение) вызовет эту ошибку. – doldt

+0

Можете ли вы подтвердить, что после присвоения '$ scope.myData = data.results;', '$ scope.myData' действительно является ожидаемым массивом? – GPicazo

+0

Если вы используете выбранный только в пользовательском интерфейсе и всегда устанавливаете значение false, зачем устанавливать его вообще? Просто установите значение true, когда оно выбрано, и значение false, если оно не выбрано. – Bryant

ответ

0

, чтобы добавить свойство к использованию объекта underscorejs,

«каждый _.each (список, iteratee, [контекст]) Псевдоним: Foreach итерацию через список элементов, дающие каждый в свою очередь, к функции iteratee Итератор привязан к объекту context, если он передан. Каждый вызов iteratee вызывается с тремя аргументами: (element, index, list). Если list является объектом JavaScript, аргументы iteratee будут (значение, ключ, список). Возвращает список для цепочки. "

«extend_.extend (destination, * sources) Скопируйте все свойства исходных объектов в объект назначения и верните целевой объект. Он находится в порядке, поэтому последний источник переопределяет свойства одно и то же имя в предыдущих аргументах. "

$scope.myData = data.results; 
// Add a "Selected" property to each object 

_.each($scope.myData, function(ent) { 
    _.extend(ent, { 
     Selected : false 
    }); 
}); 
0

Ваш отладчик screenshot на самом деле дает вам сообщение об ошибке более полезным, чем то, что вы вывесили (курсив мой):

Невозможно назначить только для чтения свойство «Selected» от 0

Это показывает, что вместо объекта вы получаете номер в качестве переменной item (в данном случае 0). Присвоение свойств примитивам в строгом режиме бросает эту ошибку «Невозможно присвоить свойство только для чтения». (Без строгого режима, он просто не может молча.)

Как JcT отметил в комментарии, это потому, что $.each вызывает функцию с 2 Params прошли, индекс первого, значение второго.Смотрите documentation of $.each:

обратного вызова

Тип: Function (Integer indexInArray, значение объекта)

Так что даже если вы назвали ваш параметр item, он получил значение текущего индекса вместо. Это означает, что ваш код можно устранить, просто добавив этот недостающий первый параметр в ваш обратный вызов, например:

function getData() { 
    myService.getData() 
     .then(function(data) { 
      $scope.myData = data.results; 
      // Add a "Selected" property to each object 
      $.each($scope.myData, function(index, item) { //index was added here! 
       item.Selected = false; 
      }); 
}