AngularJS - как изменить значение ngModel в пользовательской директиве?
Давайте посмотрим на мою директиву:
angular.module('main').directive('datepicker', [
function() {
return {
require: '?ngModel',
link: function(scope, element, attributes, ngModel) {
ngModel.$modelValue = 'abc'; // this does not work
// how do I change the value of the model?
Итак, как мне изменить значение ng-модели?
Ответы
Ответ 1
Существуют разные способы сделать это:
-
$setViewValue()
обновляет представление и модель. В большинстве случаев этого достаточно.
- Если вы хотите отключить представление от модели (например, модель представляет собой число, но представление представляет собой строку с разделителями тысяч), вы можете получить доступ непосредственно к
$viewValue
и $modelValue
- Если вы также хотите перезаписать содержимое
ng-model
(например, директива изменяет количество десятичных знаков, обновляя также модель), введите ngModel: '='
в область действия и установите scope.ngModel
например.
return {
restrict: 'A',
require: 'ngModel',
scope: {
ngModel: '='
},
link: function (scope, element, attrs, ngModelCtrl) {
function updateView(value) {
ngModelCtrl.$viewValue = value;
ngModelCtrl.$render();
}
function updateModel(value) {
ngModelCtrl.$modelValue = value;
scope.ngModel = value; // overwrites ngModel value
}
...
LINKS:
Ответ 2
Чтобы работать со сложными выражениями привязки, вы должны использовать службу $parse и метод assign
.
Для получения дополнительной информации смотрите это видео из ng-conf - все о крутых вещах, которые вы можете сделать с директивой ng-model: https://www.youtube.com/watch?v=jVzymluqmg4
app.directive('datepicker', ['$parse',
function($parse) {
return {
require: '?ngModel',
link: function(scope, element, attributes, controller) {
// $parse works out how to get the value.
// This returns a function that returns the result of your ng-model expression.
var modelGetter = $parse(attributes['ngModel']);
console.log(modelGetter(scope));
// This returns a function that lets us set the value of the ng-model binding expression:
var modelSetter = modelGetter.assign;
// This is how you can use it to set the value 'bar' on the given scope.
modelSetter(scope, 'bar');
console.log(modelGetter(scope));
}
};
}
]);
Ответ 3
На самом деле вы пытаетесь работать: см. этот Plunker
Вы не видите его на входе, потому что изменение модели таким образом не вызывает controller.$render()
, чтобы установить новый controller.$viewValue
.
Но почему бы вам просто не изменить значение $scope
(если вы этого не знаете, но это было бы странно):
angular.module('main').directive('datepicker', [function() {
return {
require: '?ngModel',
link: function(scope, element, attributes, controller) {
var model = attributes['ngModel'];
scope[model] = 'bar';
}
};
}]);
И в вашем html:
<input ng-model="yourVariable" datepicker>
EDIT: (динамическое решение)
angular.module('main').directive('datepicker', [function() {
return {
require: '?ngModel',
link: function(scope, element, attributes, controller) {
// get the value of the `ng-model` attribute
var model = attributes['ngModel'];
// update the scope if model is defined
if (model) {
scope[model] = 'bar';
}
}
};
}]);
Ответ 4
Это работает для DatePicker
на моем сайте
link: function(scope, elem, attrs, ngModel) {
scope.$apply(function(){
ngModel.$viewValue = value;
}
}
Ответ 5
Вот лучшее объяснение, с которым я столкнулся. Это мне очень помогло и собрало детали из ряда других ответов здесь.
СОВЕТ: будьте внимательны, чтобы прочитать всю статью, а не читать ее, иначе вы, скорее всего, пропустите некоторые ключевые моменты!
https://www.nadeau.tv/post/using-ngmodelcontroller-with-custom-directives/