javascript - AngularJS - Värdeattributet på en textinmatningsruta ignoreras när ett ng-model används?
Om jag använder AngularJS och sätter värdet på en enkel textinmatningsruta till något som "bob" nedan, visas värdet inte om ng-model-attributet läggs till.
<input type="text"
id="rootFolder"
ng-model="rootFolders"
disabled="disabled"
value="Bob"
size="40"/>
Någon som vet om en enkel lösning för att standardisera detta input till något och behålla ng-model? Jag försökte använda en ng-bind med standardvärdet men det verkar inte fungera heller.
Svar #1
Det är önskat beteende, du bör definiera modellen i kontrollern, inte i vyn.
<div ng-controller="Main">
<input type="text" ng-model="rootFolders">
</div>
function Main($scope) {
$scope.rootFolders = 'bob';
}
Svar #2
Vojta beskrev "Angular-sättet", men om du verkligen behöver få detta att fungera, postade @urbanek nyligen en lösning med ng-init:
<input type="text" ng-model="rootFolders" ng-init="rootFolders='Bob'" value="Bob">
https://groups.google.com/d/msg/angular/Hn3eztNHFXw/wk3HyOl9fhcJ
Svar #3
Att åsidosätta inmatningsdirektivet verkar faktiskt göra jobbet. Jag gjorde några mindre ändringar i Dan Hunsakers kod:
- Lade till en kontroll för ngModel innan
$parse().assign()används på fält utan ngModel-attribut. - Korrigerade parameterns ordning i
assign()-funktionen.
app.directive('input', function ($parse) {
return {
restrict: 'E',
require: '?ngModel',
link: function (scope, element, attrs) {
if (attrs.ngModel && attrs.value) {
$parse(attrs.ngModel).assign(scope, attrs.value);
}
}
};
});
Svar #4
Det Angular-sättet
Det korrekta sättet i Angular att göra detta är att skriva en en-sidig app, använda AJAX i formulärmallen och sedan fylla den dynamiskt från modellen. Modellen fylls inte från formuläret som standard eftersom modellen är den enda sanningskällan. Istället går Angular åt andra hållet och försöker fylla formuläret från modellen.
Om du däremot inte har tid att börja om från början
Om du har en app skriven kan detta involvera ganska omfattande arkitektoniska förändringar. Om du försöker använda Angular för att förbättra ett befintligt formulär, snarare än att konstruera en hel en-sides-app från början, kan du hämta värdet från formuläret och lagra det i scopet vid länkningstid med hjälp av en direktiv. Angular kommer sedan att binda värdet i scopet tillbaka till formuläret och hålla det synkroniserat.
Använda en direktiv
Du kan använda en relativt enkel direktiv för att hämta värdet från formuläret och ladda det i den aktuella scope. Här har jag definierat ett initFromForm-direktiv.
var myApp = angular.module("myApp", ['initFromForm']);
angular.module('initFromForm', [])
.directive("initFromForm", function ($parse) {
return {
link: function (scope, element, attrs) {
var attr = attrs.initFromForm || attrs.ngModel || element.attrs('name'),
val = attrs.value;
if (attrs.type === "number") {val = parseInt(val)}
$parse(attr).assign(scope, val);
}
};
});
Du kan se att jag har definierat ett par återfall för att få ett modellnamn. Du kan använda denna direktiv tillsammans med ngModel-direktivet, eller binda till något annat än $scope om du föredrar det.
Använd det så här:
<input name="test" ng-model="toaster.test" value="hello" init-from-form />
{{toaster.test}}
Observera att detta också fungerar med textområden och nedrullningsbara menyer.
<textarea name="test" ng-model="toaster.test" init-from-form>hello</textarea>
{{toaster.test}}
