У меня есть контроллер, отвечающий за связь с API для обновления свойств пользователя, имени, адреса электронной почты и т. Д. У каждого пользователя есть данные, 'id'
которые передаются с сервера при просмотре страницы профиля.
Я хотел бы передать это значение контроллеру AngularJS, чтобы он знал, какова точка входа API для текущего пользователя. Я пытался передать значение в ng-controller
. Например:
function UserCtrl(id, $scope, $filter) {
$scope.connection = $resource('api.com/user/' + id)
и в HTML
<body ng-controller="UserCtrl({% id %})">
где {% id %}
распечатать идентификатор, отправленный с сервера. но я получаю ошибки.
Как правильно передать значение в контроллер при его создании?
javascript
angularjs
nickponline
источник
источник
Ответы:
Ноты:
Этот ответ старый. Это просто подтверждение концепции того, как можно достичь желаемого результата. Тем не менее, это может быть не лучшим решением в соответствии с некоторыми комментариями ниже. У меня нет никакой документации, чтобы поддержать или отклонить следующий подход. Пожалуйста, обратитесь к некоторым комментариям ниже для дальнейшего обсуждения этой темы.
Оригинальный ответ:
Я ответил на это Да, вы можете сделать это, используя
ng-init
простую функцию инициализации.Вот пример этого на плункере
HTML
JavaScript
источник
The only appropriate use of ngInit for aliasing special properties of ngRepeat, as seen in the demo below. Besides this case, you should use controllers rather than ngInit to initialize values on a scope.
ng-init
произойдет - см. plnkr.co/edit / donCm6FRBSX9oENXh9WJ? p = Предварительный просмотрЯ очень опоздал к этому, и я понятия не имею, если это хорошая идея, но вы можете включить
$attrs
инъекцию в функцию контроллера, позволяющую инициализировать контроллер, используя «аргументы», предоставленные для элемента, напримерОпять же, не знаю, если это хорошая идея, но она, кажется, работает и является другой альтернативой.
источник
ng-init
- если вы пытаетесь привязать к значению области действия, он уже запускает функцию контроллера до того, как этоng-init
произойдет - см. plnkr.co/edit/donCm6FRBSX9oENXh9WJ?p=previewЭто тоже работает.
Javascript:
Html:
источник
Представление не должно диктовать конфигурацию
В Angular шаблон никогда не должен диктовать конфигурацию, которая изначально присуща людям, которые хотят передавать аргументы контроллерам из файла шаблона. Это становится скользким спуском. Если параметры конфигурации жестко запрограммированы в шаблонах (например, с помощью директивы или атрибута аргумента контроллера), вы больше не сможете повторно использовать этот шаблон для чего-либо, кроме единственного использования. Вскоре вы захотите повторно использовать этот шаблон, но с другой конфигурацией, и теперь для этого вам придется либо предварительно обработать шаблоны для ввода переменных до того, как они будут переданы в angular, либо использовать массивные директивы, чтобы выплевывать гигантские значения. блоки HTML, так что вы повторно используете весь HTML контроллера, кроме div-оболочки и его аргументов. Для небольших проектов это не имеет большого значения. Для чего-то большого (что отличает угловатость) это становится ужасно быстрым.
Альтернатива: модули
Этот тип конфигурации предназначен для обработки модулей. Во многих угловых уроках люди имеют единый модуль для всего своего приложения, но на самом деле система спроектирована и полностью поддерживает множество небольших модулей, каждый из которых охватывает небольшие части всего приложения. В идеале, контроллеры, модули и т. Д. Должны быть объявлены в отдельных файлах и сшиты вместе в определенные повторяющиеся фрагменты. Когда ваше приложение разработано таким образом, вы получаете многократное использование в дополнение к простым аргументам контроллера.
В приведенном ниже примере есть 2 модуля, повторно использующих один и тот же контроллер, но каждый со своими настройками конфигурации. Эти настройки конфигурации передаются с помощью внедрения зависимостей
module.value
. Это соответствует угловому подходу, потому что у нас есть следующее: внедрение зависимостей в конструктор, повторно используемый код контроллера, многократно используемые шаблоны контроллеров (div контроллера можно легко включить в ng-include), легко тестируемая модулем система без HTML и, наконец, многократное использование модули как средство для сшивания кусков вместе.Вот пример:
Посмотрите это в действии: jsFiddle .
источник
Как @akonsu и Найджел Findlater предложить, вы можете прочитать URL , где URL является
index.html#/user/:id
с$routeParams.id
и использовать его внутри контроллера.ваше приложение:
ресурсная служба
контроллер
затем
elm
доступен в представлении в зависимости отid
.источник
Если
ng-init
это не для передачи объектов в$scope
, вы всегда можете написать свою собственную директиву. Итак, вот что я получил:http://jsfiddle.net/goliney/89bLj/
Javasript:
Html:
Но мой подход может модифицировать только те объекты, которые уже определены в контроллере.
источник
Похоже, лучшее решение для вас - это директива. Это позволяет вам все еще иметь свой контроллер, но определять для него пользовательские свойства.
Используйте это, если вам нужен доступ к переменным в области обтекания:
Используйте это, если вам не нужен доступ к переменным в области обтекания:
источник
Я нашел полезные переменные из $ routeProvider.
Например, вы используете один контроллер MyController для нескольких экранов, передавая очень важную переменную «mySuperConstant» внутрь.
Используйте эту простую структуру:
источник
Вы можете сделать это при настройке маршрутов, например, для
А потом использовать его как
Итак, здесь, когда мы настраиваем маршрут, который мы отправили: itemType, а затем извлекаем его из $ routeParams.
источник
Есть еще один способ передать параметры в контроллер, введя в свой контроллер $ routeParams и затем используя параметры URL, описанные здесь. Какой самый краткий способ прочитать параметры запроса в AngularJS?
источник
Этот вопрос старый, но я долго пытался найти ответ на эту проблему, который бы работал для моих нужд, и мне было нелегко его найти. Я полагаю, что мое следующее решение намного лучше, чем принятое в настоящее время, возможно, потому что angular добавил функциональность, так как этот вопрос был первоначально поставлен.
Краткий ответ, используя метод Module.value, позволяет передавать данные в конструктор контроллера.
Смотрите мой плункер здесь
Я создаю объект модели, затем связываю его с контроллером модуля, ссылаясь на него с именем «модель»
HTML / JS
Затем конструктор в моем контроллере принимает параметр с тем же идентификатором «модель», к которому он затем может получить доступ.
контроллер
Ноты:
Я использую ручную инициализацию начальной загрузки , которая позволяет мне инициализировать мою модель перед отправкой в angular. Это гораздо лучше работает с существующим кодом, так как вы можете подождать, чтобы настроить соответствующие данные и скомпилировать только угловое подмножество вашего приложения, когда вы этого хотите.
В планере я добавил кнопку для оповещения о значениях объекта модели, который был первоначально определен в javascript и передан в angular, просто чтобы подтвердить, что angular действительно ссылается на объект модели, а не копирует его и работает с копией.
На этой линии:
Я передаю объект MyController в функцию Module.controller, а не объявляю его как встроенную функцию. Я думаю, что это позволяет нам гораздо более четко определять наш объект контроллера, но документация Angular стремится сделать это встроенным, поэтому я подумал, что это требует разъяснений.
Я использую синтаксис «controller as» и присваиваю значения свойству «this» в MyController, а не переменную «scope». Я считаю, что это будет работать нормально, используя $ scope точно так же, назначение контроллера будет выглядеть примерно так:
и конструктор контроллера будет иметь такую подпись:
Если по какой-либо причине вы захотите, вы также можете присоединить эту модель в качестве значения второго модуля, который вы затем присоедините в качестве зависимости к первичному модулю.
Я считаю, что его решение намного лучше, чем в настоящее время принято, потому что
В большинстве других примеров, которые я видел, похоже, работает Angular, когда контроллер определяет данные модели, что для меня никогда не имело смысла, нет разделения между моделью и контроллером, что на самом деле не выглядит MVC для меня. Это решение позволяет вам действительно иметь совершенно отдельный объект модели, который вы передаете в контроллер. Также следует отметить, что если вы используете директиву ng-include, вы можете поместить все ваши угловые html в отдельный файл, полностью разделив представление модели и контроллер на отдельные модульные части.
источник
При использовании angular-ui-router это правильное решение: https://github.com/angular-ui/ui-router/wiki#resolve
По сути, вы объявляете набор зависимостей для «разрешения» до того, как будет создан экземпляр контроллера. Вы можете объявить зависимости для каждого из ваших «состояний». Эти зависимости затем передаются в «конструктор» контроллера.
источник
Один из способов сделать это - иметь отдельный сервис, который можно использовать как «сосуд» для тех аргументов, когда они являются открытыми членами данных.
источник
Мне не очень понравились какие-либо решения здесь для моего конкретного случая использования, поэтому я решил опубликовать то, что я сделал, потому что я не видел его здесь.
Я просто хотел использовать контроллер больше как директиву внутри цикла ng-repeat:
Теперь, чтобы получить доступ к
objParameter
on on внутри каждого DirectiveLikeController (или получить актуальный objParameter в ЛЮБОЕ время), все, что мне нужно сделать, это ввести $ scope и вызвать$scope.$eval('objParameter')
:Единственный реальный недостаток, который я вижу, заключается в том, что родительский контроллер должен знать, что параметр назван
objParameter
.источник
Нет, это невозможно. Я думаю, что вы можете использовать ng-init как взломать http://docs.angularjs.org/api/ng.directive:ngInit .
источник
ng-init
произойдет - см. plnkr.co/edit / donCm6FRBSX9oENXh9WJ? p = Предварительный просмотрВот решение (основанное на предложении Marcin Wyszynski), которое работает там, где вы хотите передать значение в свой контроллер, но вы явно не объявляете контроллер в html (который, как кажется, требуется ng-init) - если, например, вы визуализируете свои шаблоны с помощью ng-view и объявляете каждый контроллер для соответствующего маршрута через routeProvider.
JS
HTML
В этом решении CurrentUser - это сервис, который может быть внедрен в любой контроллер с доступным затем свойством .name.
Две заметки:
проблема, с которой я столкнулся, заключается в том, что .name устанавливается после загрузки контроллера, поэтому в качестве обходного пути у меня есть короткий тайм-аут перед отображением имени пользователя в области видимости контроллера. Есть ли аккуратный способ ожидания, пока .name не был установлен на службе?
это выглядит как очень простой способ включить текущего пользователя в ваше приложение Angular со всей аутентификацией, хранящейся вне Angular. У вас может быть файл before_filter, чтобы предотвратить вход незарегистрированных пользователей в html, где загружается ваше приложение Angular, и внутри этого html вы можете просто интерполировать имя зарегистрированного пользователя и даже его ID, если вы хотите взаимодействовать с его данными. через http запросы от вашего приложения Angular. Вы можете разрешить не зарегистрированным пользователям использовать приложение Angular с гостевым пользователем по умолчанию. Любой совет о том, почему этот подход был бы плохим, был бы желателен - это слишком легко, чтобы быть разумным!)
источник
Это расширение превосходного ответа @Michael Tiller . Его ответ работает для инициализации переменных из представления путем введения
$attrs
объекта в контроллер. Проблема возникает, если тот же контроллер вызывается$routeProvider
при навигации по маршруту. Тогда вы получите ошибку инжектора,Unknown provider : $attrsProvider
потому что$attrs
доступно только для инъекции, когда представление компилируется. Решение состоит в том, чтобы передать переменную (foo)$routeParams
при инициализации контроллера из маршрута и$attrs
при инициализации контроллера из представления. Вот мое решение.С маршрута
Это обрабатывает URL, такие как
'/mypage/bar'
. Как вы можете видеть, foo передается по параметру url, и мы предоставляем$injector
пустой объект,$attrs
чтобы не было ошибок инжектора.С точки зрения
Теперь контроллер
источник