Angular js init ng-model a partir dos valores padrão

Digamos que você tenha um formulário que tenha valores carregados do database. Como você inicializa o ng-model?

Exemplo:

 

No meu controlador, $ scope.card é indefinido inicialmente. Existe uma maneira além de fazer algo assim?

 $scope.card = { description: $('myinput').val() } 

Esse é um erro comum em novos aplicativos angulares. Você não quer escrever seus valores em seu HTML no servidor se puder evitá-lo. Se for verdade, se você puder evitar que o seu servidor renderize HTML inteiramente, melhor ainda.

Idealmente, você deseja enviar seus modelos HTML angulares e, em seguida, exibir seus valores por meio de $ http em JSON e colocá-los em seu escopo.

Então, se possível, faça isso:

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

Se você absolutamente DEVE renderizar seus valores em seu HTML do seu servidor, você poderia colocá-los em uma variável global e acessá-los com $ window:

No header da sua página, você escreveria:

    

E, em seguida, no seu controlador você conseguiria assim:

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

Espero que isso ajude.

Se você não conseguir refazer o seu aplicativo para fazer o que o @blesh sugere (puxe dados JSON para baixo com $ http ou $ resource e preencha $ scope), você pode usar o ng-init :

  

Veja também AngularJS – O atributo Value em uma checkbox de texto de input é ignorado quando há um modelo ng usado?

Esta é uma correção obviamente ausente, mas facilmente adicionada para o AngularJS. Basta escrever uma diretiva rápida para definir o valor do modelo no campo de input.

  

Aqui está minha versão:

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

IMHO a melhor solução é a diretiva @Kevin Stone, mas eu tive que atualizá-la para funcionar em todas as condições (fe select, textarea), e esta está funcionando com certeza:

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

Você pode usar uma diretiva personalizada (com suporte a textarea, select, radio e checkbox), confira esta postagem no blog https://glaucocustodio.github.io/2014/10/20/init-ng-model-from-form- campos-atributos / .

Você também pode usar dentro do seu código HTML: ng-init="card.description = 12345"

Não é recomendado pela Angular, e como mencionado acima, você deve usar exclusivamente o seu controlador.

Mas funciona 🙂

Eu tenho uma abordagem simples, porque eu tenho algumas validações e máscaras pesadas em meus formulários. Então, eu usei jquery para obter meu valor novamente e acionar o evento “change” para validações:

 $('#myidelement').val('123'); $('#myidelement').trigger( "change"); 

Como outros salientaram, não é uma boa prática inicializar dados em visualizações. No entanto, recomenda-se inicializar dados em Controladores. (veja http://docs.angularjs.org/guide/controller )

Então você pode escrever

  

e

 $scope.card = { description: 'Visa-4242' }; $http.get('/getCardInfo.php', function(data) { $scope.card = data; }); 

Desta forma, as visualizações não contêm dados e o controlador inicializa o valor enquanto os valores reais estão sendo carregados.

Se você gosta da abordagem de Kevin Stone acima, https://stackoverflow.com/a/17823590/584761 considere uma abordagem mais fácil escrevendo diretivas para tags 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); } } }; }); 

Se você seguir esse caminho, não precisará se preocupar em adicionar ng-initial a todas as tags. Define automaticamente o valor do modelo para o atributo value da tag. Se você não definir o atributo value, o padrão será uma string vazia.

Aqui está uma abordagem cinput no servidor:

     

É a mesma ideia básica das respostas mais populares sobre essa questão, exceto que $ provide.value registra um serviço que contém seus valores padrão.

Então, no servidor, você poderia ter algo como:

 { description: "Visa-4242" } 

E coloque-o na sua página através da tecnologia do lado do servidor de sua escolha. Aqui está uma essência: https://gist.github.com/exclsr/c8c391d16319b2d31a43

Esta é uma versão mais genérica das idéias mencionadas acima … Ela simplesmente verifica se existe algum valor no modelo e, caso contrário, define o valor para o 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 (exemplo de uso):

  

Eu tentei o que o @Mark Rajcok sugeriu. Está trabalhando para valores String (Visa-4242). Por favor, consulte este violino .

Do violino:

A mesma coisa que é feita no violino pode ser feita usando ng-repeat , que todo mundo poderia recomendar. Mas depois de ler a resposta dada por @Mark Rajcok, eu só queria tentar o mesmo para um formulário com uma variedade de perfis. As coisas funcionam bem até que eu tenha $ scope.profiles = [{}, {}]; código no controlador. Se eu remover este código, estou recebendo erros. Mas em cenários normais eu não consigo imprimir $scope.profiles = [{},{}]; como eu imprimo ou echo html do servidor. Será possível executar o acima, de uma maneira similar à que @Mark Rajcok fez para os valores de string como , sem ter que ecoar a parte JavaScript do servidor.

Acabei de adicionar suporte para selecionar o elemento para Ryan Montgomery “consertar”

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

});

Se você tem o valor init no URL como mypage/id , então no controlador do JS angular você pode usar location.pathname para encontrar o id e atribuí-lo ao modelo que você deseja.