2016-02-15 5 views
5

Я подумываю о переходе на Angular2 из моей доверенной магистрали (или я должен сказать, что мой босс хочет играть с новой игрушкой, которая мне в порядке), я много раз искал в Интернете и сделал несколько тестов, но я не могу найти ответ на этот простой вопрос:Angular2, сохраняйте модели синхронизации между компонентами

Могу ли я сохранить две модели в синхронизации между двумя компонентами? Пример. У меня есть список пользователей на боковой панели, который является одним компонентом, и форму для редактирования указанных пользователей на моей «главной странице», что является еще одним компонентом.

Боковая панель отвечает за получение своей коллекции для отображения, а форма отвечает за получение ее модели. Когда модель обновляется, я хочу, чтобы изменения отражались на боковой панели, не переходя снова через сервер.

Я знаю, что SpinJS это делает, и я взломал что-то в Backbone, используя события, чтобы достичь того же (на основе класса модели и id), но мне интересно, имеет ли Angular2 собственный способ обработки? Если нет, то как бы вы могли реализовать такое поведение?

Спасибо.

EDIT:

Я добавил мои тестовые файлы в этом Plunker: http://plnkr.co/edit/jIdnu68ZDMDSFJkomN3Y

Во-первых, выберите героя и нажмите кнопку «просмотреть данные», это сделает http.get запрос на сервер в памяти до получить героя.

Во-вторых, нажмите «Дать меч», это добавит Оружие выбранному пользователю. Для тестирования, вместо использования уже загруженного пользователя, я запрашиваю тот же самый, используя http.get.

Когда я изменяю имя в текстовом поле, имя второго экземпляра не обновляется.

Вы должны представить, что я не могу использовать текущий экземпляр героя по каким-либо причинам, я хочу запросить его снова с сервера.

+0

Что вы подразумеваете под «Когда я меняю имя в текстовом поле, имя второго экземпляра не обновляется». Где он должен быть обновлен? «Владелец» оружия? –

+0

Правильно, поскольку это тот же класс и тот же идентификатор, мне было интересно, есть ли способ синхронизировать их, как это делает SpineJS. – Growiel

ответ

0

Я думаю, что лучший способ сделать это - использовать EventEmitter в общей службе. Когда изменение сделано, на излучателе события выдается событие. Другие части заявки, которые зарегистрировались против нее, будут уведомлены.

Смотрите этот ответ:

1

Вы можете поделиться услуги между компонентами.

@Injectable() 
export class SharedService { 
    someField:string; 
} 

@Component({selector: 'parent-cmp', providers [SharedService], ...) 
export class ParentCmp { 
    constructor(private model:SharedServicee) { 
    } 
} 

@Component({selector: 'child-cmp', 
    // don't add it to providers here so it gets the same instance 
    // the parent got 
    /*providers [SharedService] */, ...) 
export class ChildCmp { 
    constructor(private model:SharedServicee) { 
    } 
} 

Когда один компонент меняет поле в службе, другая служба также видна в другом компоненте.

Вы можете использовать Observable или EventEmitter, чтобы уведомить заинтересованные стороны об изменениях или других событиях.

+0

Спасибо за ответ! Я уже пользуюсь совместно используемой службой, но проблема в том, что когда я делаю UserServicer.get (id), я возвращаю новый экземпляр с обновленными данными с сервера ... Может быть, решение должно отслеживать всех моих уже выбранных пользователей возвращают тот же самый экземпляр уже взятого? Кажется, что у каждой модели есть синглтон. Похоже, это приведет к тому, что модели никогда не будут собирать мусор. – Growiel

+0

Если вы поместите данные в общую службу, которую у вас уже есть, это не должно быть проблемой. Общая служба может управлять кешем, если вы хотите сохранить ранее извлеченные данные для более быстрого ответа на последовательные запросы. –

+0

Я просто попробовал эту другую попытку, и результат тот же: второй http.get() создает отдельный экземпляр модели и когда один обновляется, второй - нет. Может быть, я чего-то не хватает. – Growiel

1

Вы можете использовать общие службы для подписки на одно и то же событие в разных компонентах. (если вы предоставляете эту услугу при загрузке, она даст вам тот же объект во всех компонентах. Очень важно!).

Если вы хотите вызвать http.get только один раз, а потом просто повторить этот призыв, вы должны использовать:

private _subject = new ReplaySubject(1); 
constructor(public http: Http) { 
    this.http 
     .get("...").subscribe(this._subject); 
} 

Полный, рабочий пример: https://plnkr.co/edit/G1mSXfpuYaIGXNwK5WKy?p=preview

Посмотрите на сеть панель (хром), вызов ajax запускается только один раз.

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