У меня есть служба, содержащая некоторые контакты (имя, телефон). Контроллер имеет массив, содержащий ссылку на массив из службы, поэтому для каждого изменения в массиве все обновляется.
Обслуживание:
app.service('ContactManagerService', function()
{
this.Contacts=[];
...
this.AddContact=function(Contact){...};
this.RemoveContact=function(Contact){...};
...
});
Первый вопрос: это хороший подход? Должен ли каждый контроллер/директива иметь прямую ссылку на исходный массив из службы? Я много читал о настройке некоторых событий из службы на контроллеры, когда массив был изменен, но это звучит глупо, потому что массив на контроллере будет в любом случае изменен (потому что его тот же массив) и ng-repeat будут обновляться автоматически.
Вторая проблема. У службы есть метод, который заменяет массив на новый:
this.ReplaceContacts=function(NewContacts)
{
this.Contacts=NewContacts;
});
Ng-repeat не обновляется, поскольку контроллер по-прежнему получает старую ссылку на старый массив. Так что нужно обновить.
Я попытался заменить код на этот, поэтому одна и та же ссылка на массив не изменится, но когда код войдет в foreach, этот массив.Contacts не определен и код останавливается. Зачем?!
this.ReplaceContacts=function(NewContacts)
{
this.Contacts.splice(0, this.Contacts.length); //remove all contacts
NewContacts.forEach(function (contact, index)
{
this.Contacts.push(contact);//place the new ones
});
});
Код контроллера:
app.controller("myCtrl",
function ($scope,ContactManagerService)
{
$scope.Contacts = ContactManagerService.Contacts;
$scope.AddContact= function (Contact1) {
ContactManagerService.AddContact(Contact1);
}
$scope.RemoveContact = function (ContactID) {
ContactManagerService.RemoveContact(ContactID);
}
});
Надеюсь, все ясно, спасибо.
Поскольку функция обратного вызова, передаваемая forEach
, не привязана к экземпляру службы. Таким this
, внутри обратного вызова это не сервис.
Мой совет: избегай this
как чума. Это огромный источник ошибок в JavaScript.
использование
var self = this;
в верхней части службы, и вместо this
используйте " self
.
Или привяжите функцию обратного вызова к экземпляру службы:
NewContacts.forEach(function (contact, index) {
...
}, this);
this
(услугу) переменные self
, и , таким образом , эти переменный будет указывать на службу , как this
делает. За исключением того, что self
всегда будет указывать на сервис, а this
не всегда, в зависимости от того, где вы его используете (как, например, в функции обратного вызова).
Как уже упоминалось в предыдущем anser, контекст this
цикла forEach - это не то, что вы думаете.
Упрощение будет заключаться в использовании Array.prototype.concat()
:
var self = this;
self.ReplaceContacts = function (NewContacts) {
self.Contacts.splice(0, this.Contacts.length); //remove all contacts
self.Contacts.concat(NewContacts);
});
Вы можете просто перетаскивать элементы в Contacts
с помощью Array.prototype.push()
Метод push() добавляет один или несколько элементов в конец массива и возвращает новую длину массива.
this.ReplaceContacts=function(NewContacts){
this.Contacts.splice(0, this.Contacts.length); //remove all contacts
Array.prototype.push(this.Contacts, NewContacts);
});