javascript - directivas - AngularJS: ¿cómo cambiar el valor de ngModel en una directiva personalizada?
ng angular (5)
Echemos un vistazo a mi directiva:
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?
Entonces, ¿cómo cambio el valor del ng-model?
Esta es la mejor explicación que he encontrado. Esto me ayudó a lo grande, y reúne detalles de varias otras respuestas aquí.
CONSEJO: ¡Tenga cuidado de leer todo el artículo en lugar de echarle un vistazo, o de lo contrario es probable que se pierda algunas partes clave!
https://www.nadeau.tv/using-ngmodelcontroller-with-custom-directives/
Esto funciona para un DatePicker
en mi sitio
link: function(scope, elem, attrs, ngModel) {
scope.$apply(function(){
ngModel.$viewValue = value;
}
}
Hay diferentes formas de hacerlo:
-
$setViewValue()
actualiza la vista y el modelo. La mayoría de los casos es suficiente. - Si desea desconectar la vista del modelo (por ejemplo, el modelo es un número pero la vista es una cadena con separadores de miles), entonces podría acceder directamente a
$viewValue
y$modelValue
- Si también desea sobrescribir el contenido de
ng-model
(por ejemplo, la directiva cambia el número de decimales, actualizando también el modelo), inyectengModel: ''=''
en el alcance y establezcascope.ngModel
p.ej
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
}
...
CAMPO DE GOLF:
- La primera opción se discute here
- NgModelController oficiales de NgModelController
Lo que probaste realmente está funcionando: mira este Plunker
No lo "ve" en la entrada porque cambiar el modelo de esta manera no llama al controller.$render()
para configurar el nuevo controller.$viewValue
.
Pero ¿por qué no simplemente cambias el valor de $scope
(a menos que no lo sepas, pero sería extraño):
angular.module(''main'').directive(''datepicker'', [function() {
return {
require: ''?ngModel'',
link: function(scope, element, attributes, controller) {
var model = attributes[''ngModel''];
scope[model] = ''bar'';
}
};
}]);
Y en tu html:
<input ng-model="yourVariable" datepicker>
EDITAR: (solución dinámica)
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'';
}
}
};
}]);
Para trabajar con expresiones de enlace complejas, debe usar el servicio $parse y el método de assign
.
Para obtener más información, mire este video de ng-conf: se trata de las cosas geniales que puede hacer con la directiva 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));
}
};
}
]);