Angular js init ng-model от значений по умолчанию
Скажите, что у вас есть форма, которая имеет значения, загруженные из базы данных. Как вы инициализируете ng-модель?
Пример:
<input name="card[description]" ng-model="card.description" value="Visa-4242">
В моем контроллере $scope.card является undefined изначально. Есть ли способ сделать что-то подобное?
$scope.card = {
description: $('myinput').val()
}
Ответы
Ответ 1
Это распространенная ошибка в новых приложениях Angular. Вы не хотите записывать свои значения в свой HTML на сервере, если можете избежать этого. Если факт, если вы можете уйти от того, чтобы ваш сервер полностью отображал HTML, тем лучше.
В идеале вы хотите отправить свои HTML-шаблоны Angular, а затем потяните свои значения через $http в JSON и поместите их в свою область.
Итак, если это вообще возможно, сделайте следующее:
app.controller('MyController', function($scope, $http) {
$http.get('/getCardInfo.php', function(data) {
$scope.card = data;
});
});
<input type="text" ng-model="card.description" />
Если вы абсолютно ДОЛЖНЫ отображать свои значения в своем HTML с вашего сервера, вы можете поместить их в глобальную переменную и получить к ним доступ с помощью $window:
В заголовке вашей страницы вы выписываете:
<head>
<script>
window.card = { description: 'foo' };
</script>
</head>
И затем в вашем контроллере вы получите следующее:
app.controller('MyController', function($scope, $window) {
$scope.card = $window.card;
});
Я надеюсь, что это поможет.
Ответ 2
Если вы не можете переделать свое приложение, чтобы сделать то, что предлагает @blesh (вытащите данные JSON вниз с помощью $http или $resource и заполните пробел $), вы можете использовать ng-init:
<input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'">
См. также AngularJS - Атрибут Value во входном текстовом поле игнорируется при использовании ng-модели?
Ответ 3
Это явно недостающее, но легко добавленное исправление для AngularJS. Просто напишите краткую директиву, чтобы установить значение модели из поля ввода.
<input name="card[description]" value="Visa-4242" ng-model="card.description" ng-initial>
Здесь моя версия:
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);
}
]
};
});
Ответ 4
IMHO лучшим решением является директива @Kevin Stone, но мне пришлось обновить его, чтобы работать в любых условиях (например, 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);
}
}
}
}
});
Ответ 5
Вы можете использовать настраиваемую директиву (с поддержкой текстового поля, выберите, радио и флажок), посмотрите этот пост в блоге https://glaucocustodio.github.io/2014/10/20/init-ng-model-from-form-fields-attributes/.
Ответ 6
Вы также можете использовать код HTML:
ng-init="card.description = 12345"
Не рекомендуется использовать Angular, и, как упоминалось выше, вы должны использовать исключительно ваш контроллер.
Но он работает:)
Ответ 7
У меня простой подход, потому что у меня есть некоторые тяжелые проверки и маски в моих формах. Итак, я использовал jquery, чтобы снова получить мое значение и запустить событие "change" для проверки:
$('#myidelement').val('123');
$('#myidelement').trigger( "change");
Ответ 8
Как указывали другие, нецелесообразно инициализировать данные по представлениям.
Однако рекомендуется инициализировать данные на контроллерах. (см. http://docs.angularjs.org/guide/controller)
Итак, вы можете написать
<input name="card[description]" ng-model="card.description">
и
$scope.card = { description: 'Visa-4242' };
$http.get('/getCardInfo.php', function(data) {
$scope.card = data;
});
Таким образом, представления не содержат данных, а контроллер инициализирует значение при загрузке реальных значений.
Ответ 9
Если вам нравится подход Кевина Стоуна выше fooobar.com/questions/47004/...
рассмотрите более простой подход, написав директивы для определенных тегов, таких как "enter".
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, по умолчанию будет пустая строка.
Ответ 10
Вот ориентированный на сервер подход:
<html ng-app="project">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script>
// Create your module
var dependencies = [];
var app = angular.module('project', dependencies);
// Create a 'defaults' service
app.value("defaults", /* your server-side JSON here */);
// Create a controller that uses the service
app.controller('PageController', function(defaults, $scope) {
// Populate your model with the service
$scope.card = defaults;
});
</script>
<body>
<div ng-controller="PageController">
<!-- Bind with the standard ng-model approach -->
<input type="text" ng-model="card.description">
</div>
</body>
</html>
Это та же основная идея, что и более популярные ответы на этот вопрос, кроме $provided.value регистрирует сервис, который содержит ваши значения по умолчанию.
Итак, на сервере у вас может быть что-то вроде:
{
description: "Visa-4242"
}
И разместите его на своей странице с помощью технологии на стороне сервера по вашему выбору. Здесь Gist: https://gist.github.com/exclsr/c8c391d16319b2d31a43
Ответ 11
Я попробовал, что предложил @Mark Rajcok. Он работает для значений String (Visa-4242).
Пожалуйста, обратитесь к fiddle.
Из скрипта:
То же самое, что сделано в скрипке, можно сделать с помощью ng-repeat
, который каждый мог бы порекомендовать. Но после прочтения ответа, данного @Mark Rajcok, я просто хотел попробовать то же самое для формы с массивом профилей.
Все работает хорошо, пока у меня нет $scope.profiles = [{}, {}]; кода в контроллере. Если я удалю этот код, я получаю ошибки.
Но в обычных сценариях я не могу напечатать $scope.profiles = [{},{}];
как я print или echo html с сервера.
Можно ли выполнить описанное выше, аналогично тому, как @Mark Rajcok сделал для строковых значений, таких как <input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'">
, без необходимости отгонять часть JavaScript с сервера.
Ответ 12
Это более общая версия упомянутых выше идей...
Он просто проверяет, есть ли какое-либо значение в модели, а если нет, оно задает значение модели.
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 (пример использования):
<select class="form-control"
ng-options="v for (i, v) in compressionMethods"
ng-model="action.parameters.Method"
default-value="'LZMA2'"></select>
Ответ 13
Просто добавлена поддержка выбранного элемента для Ryan Montgomery "fix"
<select class="input-control" ng-model="regCompModel.numberOfEmployeeId" ng-initial>
<option value="1af38656-a752-4a98-a827-004a0767a52d"> More than 500</option>
<option value="233a2783-db42-4fdb-b191-0f97d2d9fd43"> Between 250 and 500</option>
<option value="2bab0669-550c-4555-ae9f-1fdafdb872e5"> Between 100 and 250</option>
<option value="d471e43b-196c-46e0-9b32-21e24e5469b4"> Between 50 and 100</option>
<option value="ccdad63f-69be-449f-8b2c-25f844dd19c1"> Between 20 and 50</option>
<option value="e00637a2-e3e8-4883-9e11-94e58af6e4b7" selected> Less then 20</option>
</select>
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)
}]
}
});
Ответ 14
Если у вас есть значение init в URL, например mypage/id
, то в контроллере angular JS вы можете использовать location.pathname
, чтобы найти идентификатор и назначить его желаемой модели.