Angular js init ng-modelo a partir de valores predeterminados


Supongamos que tiene un formulario que tiene valores cargados desde la base de datos. ¿Cómo inicializar ng-model?

Ejemplo:

<input name="card[description]" ng-model="card.description" value="Visa-4242">

En mi controlador, scope scope.la tarjeta es indefinida inicialmente. ¿Hay alguna manera además de hacer algo como esto?

$scope.card = {
  description: $('myinput').val()
}
 126
Author: Calvin Froedge, 2012-12-07

14 answers

Este es un error común en nuevas aplicaciones Angulares. No desea escribir sus valores en su HTML en el servidor si puede evitarlo. De hecho, si puede evitar que su servidor renderice HTML por completo, mucho mejor.

Idealmente, desea enviar sus plantillas HTML angulares, luego bajar sus valores a través de http http en JSON y colocarlos en su ámbito.

Así que si es posible, haz esto:

app.controller('MyController', function($scope, $http) {
    $http.get('/getCardInfo.php', function(data) {
       $scope.card = data;
    });
});

<input type="text" ng-model="card.description" />

Si es absolutamente NECESARIO renderizar sus valores en su HTML desde su servidor, puede colocarlos en una variable global y acceder a ellos con window window:

En el encabezado de tu página escribirías:

<head>
   <script>
       window.card = { description: 'foo' };
   </script>
</head>

Y luego en tu controlador lo obtendrías así:

app.controller('MyController', function($scope, $window) {
   $scope.card = $window.card;
});

Espero que eso ayude.

 135
Author: Ben Lesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-07 21:24:44

Si no puedes volver a trabajar tu aplicación para hacer lo que @ blesh sugiere (bajar los datos JSON con http http o resource resource y rellenar scope scope), puedes usar ng-init en su lugar:

<input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'">

Ver también El atributo AngularJS - Value en un cuadro de texto de entrada se ignora cuando se utiliza un modelo ng?

 236
Author: Mark Rajcok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:24

Esta es una solución obviamente deficiente, pero fácil de agregar para AngularJS. Simplemente escriba una directiva rápida para establecer el valor del modelo desde el campo de entrada.

<input name="card[description]" value="Visa-4242" ng-model="card.description" ng-initial>

Aquí está mi versión:

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);
      }
    ]
  };
});
 60
Author: Kevin Stone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-13 07:39:56

En mi humilde opinión, la mejor solución es la directiva @Kevin Stone, pero tuve que actualizarla para que funcionara en todas las condiciones (por ejemplo, select, textarea), y esta funciona con seguridad:

    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);
                    }
                }
            }
        }
    });
 12
Author: jtompl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-13 14:22:20

Puedes usar una directiva personalizada (con soporte para textarea, select, radio y checkbox), echa un vistazo a esta entrada de blog https://glaucocustodio.github.io/2014/10/20/init-ng-model-from-form-fields-attributes/.

 7
Author: user1519240,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-12 18:57:20

También se puede utilizar dentro de su código HTML: ng-init="card.description = 12345"

Angular no lo recomienda, y como se mencionó anteriormente, debe usar exclusivamente su controlador.

Pero funciona :)

 6
Author: koxon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-16 04:30:25

Tengo un enfoque simple, porque tengo algunas validaciones pesadas y máscaras en mis formas. Por lo tanto, he utilizado jquery para obtener mi valor de nuevo y disparar el evento "cambiar" a validaciones:

$('#myidelement').val('123');
$('#myidelement').trigger( "change");
 4
Author: Guilherme Redmer Machado,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-18 01:39:09

Como otros señalaron, no es una buena práctica inicializar los datos sobre las opiniones. Sin embargo, se recomienda inicializar los datos en los Controladores. (véase http://docs.angularjs.org/guide/controller )

Para que puedas escribir

<input name="card[description]" ng-model="card.description">

Y

$scope.card = { description: 'Visa-4242' };

$http.get('/getCardInfo.php', function(data) {
   $scope.card = data;
});

De esta manera las vistas no contienen datos, y el controlador inicializa el valor mientras se cargan los valores reales.

 3
Author: Jkarttunen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-13 12:54:31

Si te gusta el enfoque de Kevin Stone anterior https://stackoverflow.com/a/17823590/584761 considere un enfoque más fácil escribiendo directivas para etiquetas específicas como'input'.

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);
            }
        }
    }; });

Si vas por esta ruta no tendrás que preocuparte por añadir ng-initial a cada etiqueta. Establece automáticamente el valor del modelo en el atributo value de la etiqueta. Si no establece el atributo value, el valor predeterminado será una cadena vacía.

 3
Author: coder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:47

Aquí hay un enfoque centrado en el servidor:

<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>

Es la misma idea básica que las respuestas más populares sobre esta pregunta, excepto provide proporcionar.value registra un servicio que contiene sus valores predeterminados.

Entonces, en el servidor, podrías tener algo como:

{
    description: "Visa-4242"
}

Y póngalo en su página a través de la tecnología del lado del servidor de su elección. He aquí una esencia: https://gist.github.com/exclsr/c8c391d16319b2d31a43

 3
Author: exclsr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-04 01:33:51

Esta es una versión más genérica de las ideas mencionadas anteriormente... Simplemente comprueba si hay algún valor en el modelo, y si no, se establece el valor en el modelo.

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 (ejemplo de uso):

<select class="form-control"
        ng-options="v for (i, v) in compressionMethods"
        ng-model="action.parameters.Method"
        default-value="'LZMA2'"></select>
 1
Author: Eitan H.S.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-17 22:12:19

Probé lo que @Mark Rajcok sugirió. Funciona para valores de cadena (Visa-4242). Por favor, consulte este violín.

Del violín:

Lo mismo que se hace en el violín se puede hacer usando ng-repeat, que todo el mundo podría recomendar. Pero después de leer la respuesta dada por @ Mark Rajcok, solo quería probar lo mismo para un formulario con matriz de perfiles. Las cosas funcionan bien hasta que tengo el scope alcance.profiles = [{}, {}]; código en el controlador. Si elimino este código, estoy recibiendo error. Pero en escenarios normales no puedo imprimir $scope.profiles = [{},{}]; ya que imprimo o echo html desde el servidor. ¿Será posible ejecutar lo anterior, de manera similar a lo que hizo @Mark Rajcok para los valores de cadena como <input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'">, sin tener que hacer eco de la parte JavaScript del servidor.

 0
Author: Rajkamal Subramanian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-20 03:32:49

Acaba de agregarse soporte para select element a 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)
    }]
}

});

 0
Author: kolesso,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-01 10:45:12

Si tiene el valor init en la URL como mypage/id, entonces en el controlador del JS angular puede usar location.pathname para encontrar el id y asignarlo al modelo que desee.

 0
Author: Neon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-31 06:11:49