2013-07-15 2 views
2

Друзья ..Угловая область не сохраняющая ценность

Для моего понимания того, как работает маршрутизация в Угловом, я создал простое приложение. Это приложение имеет только две страницы: 1. На первой странице будут отображаться все строки таблицы сотрудников. При нажатии на определенную строку вторая страница отобразит форму с данными этого сотрудника.

список, который отображается на первой странице используется следующий код:

<table> 
    <tr ng-repeat="employee in employees"> 
     <td>{{employee.firstname}} - {{employee. address}}</td>   
     <td><span ng-click="getSingleEmployeeDetails(employee.id)">Edit</a></td> 
    </tr> 
</table> 

Я использую тот же контроллер для обоих этих страниц и этот контроллер выглядит следующим образом:

function EmployeeCtrl($scope,$http,Employee,$location,$routeParams) { 
    // Get all employee details 
    var data; 
    Employee.query().then(function(_data) { 
     $scope.employees = _data.data;    
    }); 

    // Get Single Employee Details 
    $scope.getSingleEmployeeDetails = function(id) { 
     $scope.employee = scope.employees[id]; 
     $location.path('/editemployee/' + id); 
    } 
} 

Однако проблема, с которой я сталкиваюсь, заключается в том, что когда код отправляется в/editemployee/1
по какой-то причине $ scope.employees теряет свои значения.

Другими словами, форма никогда не заполняется деталями сотрудника.

Что я здесь делаю неправильно?

+3

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

+0

На самом деле, если вы посмотрите на этот пример Джона Линдквиста, он, кажется, использует $ scope одного контроллера в другой при изменении маршрута. Как он может это сделать? http://www.youtube.com/watch?v=5uhZCc0j9RY&list=PLdVInYVbR-1wfi5AnAqhKwXf_PYrscUNU – runtimeZero

+0

Наследование области происходит, если обе области активны в то же время, я полностью рекомендую видео Джона, хотя в egghead.io было мое первое погружение в Угловое и я все еще возвращаюсь совсем немного. – shaunhusain

ответ

0

Это связано с областью обзора. Сотрудники загружаются в EmployeeCtrl при его создании. Когда вы выполняете событие маршрутизации в getSingleEmployeeDetails(), это приводит к тому, что другой контроллер загружается с другой $ -ой областью. Область $, которая отделена от $ scope внутри EmployeeCtrl. Один простой способ - позволить EmployeeCtrl обрабатывать функциональность загрузки/отображения всех сотрудников и одного сотрудника без маршрутизации на новый контроллер. Преимуществом здесь является то, что он упрощает обмен информацией, и вам не нужно перезагружать информацию одного сотрудника, когда пользователь нажимает на одного сотрудника, потому что вы можете делиться этой информацией более легко. Согласитесь, вы не вернетесь к навигации по кнопкам, чтобы перемещаться между выборами отдельных сотрудников.

Другой вариант - позволить SingleEmployeeCtrl перезагружать информацию при ее навигации. Про - вы снова получаете доступ к кнопке, но con вы загружаете информацию дважды (один раз для загрузки полного списка и дважды для загрузки информации о сотрудниках). Это также позволяет пользователю закладок отдельных записей сотрудников, но кто больше закладок?

+0

Третий вариант, используемый как singleton и A) возвращает обещание для данных, или B) - $ watch (ed) внутри контроллеров. Теперь это выбор собственного приключения. – shaunhusain

+0

Чтобы все было в порядке, я пытаюсь достичь первого результата. Пусть один контроллер управляет вещами. Как мне это сделать? С момента загрузки страницы EditEmployee.html контроллер теряет свою $ scope. – runtimeZero

+0

@JamesHans вы можете использовать директиву ng-include или, возможно, ng-if, чтобы включать страницы/представления, когда какая-либо переменная установлена ​​на определенное значение. Таким образом, вы удаляете запись страницы с маршрутов и вместо обновления $ location вы просто обновите свою переменную. Это «ломает» маршрутизацию/глубокую привязку, как здесь указывают chubbsondubs. Чтобы исправить маршрутизацию, вы также можете прослушать событие изменения маршрута и вручную обновить переменную в своем контроллере (хотя немного взломать) – shaunhusain

0

Другие уже объяснили, что при изменении маршрутов создается новый контроллер (и $ scope). Также обратите внимание, что $ scope.employees заселяется асинхронно, когда обещание будет разрешено. Вероятно, происходит то, что getSingleEmployeeDetails() вызывается до того, как обетование будет разрешено, поэтому массив employees пуст.

Чтобы решить эту проблему, я предлагаю другую архитектуру.

У вас есть два вида/страниц. Каждый вид в Angular обычно имеет свой собственный контроллер. Модели/данные обычно хранятся в службах, и API для извлечения и управления этими моделями/данными становится доступным/общедоступным службой. Контроллер просто склеивает все вместе: он вводит необходимые ему службы (службы), а затем ссылается только на те модели/данные, которые необходимы для соответствующего представления.

Итак, несмотря на то, что ваше приложение прост, я предлагаю вышеупомянутый подход: одна служба (в которой хранятся объекты сотрудника), два контроллера, два вида. В частности, поместите вызов query() в вашу службу (поэтому он будет вызываться один раз, когда создается служба) и хранить ваши данные в службе.API-интерфейс службы должен определять функции/методы, которые возвращают обещание, которое в конечном итоге будет содержать требуемые данные (список сотрудников или только один). Контроллеры должны использовать эти методы для получения ссылки на нужные данные.

См. Также Should services expose their asynchronicity? для примера того, как хранить данные в службе.

+0

Спасибо, Марк .. эта архитектура очищает некоторые моменты для меня. Теперь я включил службу, но не уверен, как включать вызовы POST в эту службу. Просьба проверить мой измененный вопрос – runtimeZero

+0

@JamesHans, передать измененный объект сотрудника в качестве аргумента в метод API, который вы определяете в службе. Этот метод службы вызовет $ http.post() от имени контроллера. –

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