Угловая js init ng-model от значений по умолчанию
Скажем, у вас есть форма, которая имеет значения, загруженные из базы данных. Как вы инициализируете ng-модель?
Пример:
В моем controllerе $ scope.card сначала не определена. Есть ли способ сделать что-то подобное?
- Функция пользовательской сортировки в ng-repeat
- Создать простой бутстрап Да / Нет подтверждение или просто уведомление в AngularJS
- Удаление идентификатора fragmentа из URL-адресов AngularJS (символ #)
- angularjs перемещает фокус на следующий элемент управления при вводе
- Как перебирать элементы, возвращаемые функцией с помощью ng-repeat?
$scope.card = { description: $('myinput').val() }
- Отправить FormData с другим полем в Angular
- Ng-click не работает внутри ng-repeat
- Понимание опции transclude определения директивы?
- Реализация загрузчика с использованием httpInterceptor и AngularJS 1.1.5
- Угловой фильтр работает, но приводит к тому,
- Угловые коды / соглашения об именах
- Как / когда использовать ng-click для вызова маршрута?
- AngularJS - Зачем использовать «Controller as vm»?
Это распространенная ошибка в новых угловых приложениях. Вы не хотите записывать свои значения в свой HTML на сервере, если можете избежать этого. Если факт, если вы можете уйти от того, чтобы ваш сервер отображал HTML целиком, тем лучше.
В идеале вы хотите отправить свои угловые HTML-шаблоны, а затем вытащите свои значения через $ http в JSON и поместите их в свою область.
Поэтому, если это вообще возможно, сделайте следующее:
app.controller('MyController', function($scope, $http) { $http.get('/getCardInfo.php', function(data) { $scope.card = data; }); });
Если вы абсолютно ДОЛЖНЫ отображать свои значения в своем HTML с вашего сервера, вы можете поместить их в глобальную переменную и получить к ним доступ с помощью windows $ window:
В заголовке своей страницы вы выписываете:
И тогда в вашем controllerе вы получите его так:
app.controller('MyController', function($scope, $window) { $scope.card = $window.card; });
Надеюсь, это поможет.
Если вы не можете переработать свое приложение, чтобы сделать то, что предлагает @blesh (вытащите данные JSON вниз с помощью $ http или $ resource и заполните пробел $), вы можете вместо этого использовать ng-init :
См. Также AngularJS. Атрибут Value во входном текстовом поле игнорируется при использовании ng-модели?
Это явно недостающее, но легко добавленное исправление для AngularJS. Просто напишите краткую директиву, чтобы установить значение модели из поля ввода.
Вот моя версия:
var app = angular.module('forms', []); app.directive('ngInitial', function() { return { restrict: 'A', controller: [ '$scope', '$element', '$attrs', '$parse', function($scope, $element, $attrs, $parse) { var getter, setter, val; val = $attrs.ngInitial || $attrs.value; getter = $parse($attrs.ngModel); setter = getter.assign; setter($scope, val); } ] }; });
ИМХО лучшим решением является директива @Kevin Stone, но мне пришлось обновить ее для работы в любых условиях (fe select, textarea), и это верно:
angular.module('app').directive('ngInitial', function($parse) { return { restrict: "A", compile: function($element, $attrs) { var initialValue = $attrs.value || $element.val(); return { pre: function($scope, $element, $attrs) { $parse($attrs.ngModel).assign($scope, initialValue); } } } } });
Вы можете использовать специальную директиву (с поддержкой текстового поля, выбора, радио и флажка), посмотрите этот пост в блоге https://glaucocustodio.github.io/2014/10/20/init-ng-model-from-form- fields-attributes / .
Вы также можете использовать в своем HTML-коде: ng-init="card.description = 12345"
Это не рекомендуется Angular, и, как упоминалось выше, вы должны использовать исключительно ваш controller.
Но это работает 🙂
У меня простой подход, потому что у меня есть некоторые тяжелые проверки и маски в моих формах. Итак, я использовал jquery, чтобы снова получить мою ценность и запустить событие «change» для проверки:
$('#myidelement').val('123'); $('#myidelement').trigger( "change");
Как отмечали другие, нецелесообразно инициализировать данные по мнениям. Однако рекомендуется инициализировать данные на controllerах. (см. http://docs.angularjs.org/guide/controller )
Таким образом, вы можете написать
а также
$scope.card = { description: 'Visa-4242' }; $http.get('/getCardInfo.php', function(data) { $scope.card = data; });
Таким образом, представления не содержат данных, и controller инициализирует значение при загрузке реальных значений.
Если вам нравится подход Кевина Стоуна выше https://stackoverflow.com/a/17823590/584761, рассмотрите более простой подход, написав директивы для определенных тегов, таких как «ввод».
app.directive('input', function ($parse) { return { restrict: 'E', require: '?ngModel', link: function (scope, element, attrs) { if (attrs.ngModel) { val = attrs.value || element.text(); $parse(attrs.ngModel).assign(scope, val); } } }; });
Если вы идете по этому маршруту, вам не придется беспокоиться о добавлении ng-initial для каждого тега. Он автоматически устанавливает значение модели в атрибут значения тега. Если вы не установите атрибут value, по умолчанию будет пустая строка.
Вот ориентированный на сервер подход:
Это та же основная идея, что и более популярные ответы на этот вопрос, за исключением того, что $ provided.value регистрирует сервис, который содержит ваши значения по умолчанию.
Итак, на сервере у вас может быть что-то вроде:
{ description: "Visa-4242" }
И поместите его на свою страницу с помощью технологии на стороне сервера по вашему выбору. Вот суть: https://gist.github.com/exclsr/c8c391d16319b2d31a43
Это более общая версия упомянутых выше идей … Она просто проверяет, есть ли какое-либо значение в модели, а если нет, оно задает значение модели.
JS:
function defaultValueDirective() { return { restrict: 'A', controller: [ '$scope', '$attrs', '$parse', function ($scope, $attrs, $parse) { var getter = $parse($attrs.ngModel); var setter = getter.assign; var value = getter(); if (value === undefined || value === null) { var defaultValueGetter = $parse($attrs.defaultValue); setter($scope, defaultValueGetter()); } } ] } }
HTML (пример использования):
Я попробовал, что предложил @Mark Rajcok. Он работает для значений String (Visa-4242). Пожалуйста, обратитесь к этой скрипке .
Со скрипки:
То же самое, что делается в скрипке, можно сделать с помощью ng-repeat
, который каждый мог бы порекомендовать. Но после прочтения ответа, данного @Mark Rajcok, я просто хотел попробовать то же самое для формы с массивом профилей. Все работает хорошо, пока у меня нет $ scope.profiles = [{}, {}]; кода в controllerе. Если я удалю этот код, я получаю ошибки. Но в обычных сценариях я не могу напечатать $scope.profiles = [{},{}];
как i print или echo html с сервера. Можно ли выполнить вышеупомянутое, так же, как @Mark Rajcok сделал для строковых значений, таких как , не отрываясь от части JavaScript с сервера.
Просто добавлена поддержка выбранного элемента Ryan Montgomery “fix”
app.directive('ngInitial', function () { return { restrict: 'A', controller: ['$scope', '$element', '$attrs', '$parse', function ($scope, $element, $attrs, $parse) { val = $attrs.sbInitial || $attrs.value || $element.val() || $element.text() getter = $parse($attrs.ngModel) setter = getter.assign setter($scope, val) }] }
});
Если у вас есть значение init в URL-адресе, например mypage/id
, то в controllerе углового JS вы можете использовать location.pathname
чтобы найти идентификатор и назначить его желаемой модели.