AngularJS-ngモデルが使用されている場合、入力テキストボックスの値属性は無視されますか?


218

単純な入力テキストボックスの値を下の「bob」のような値に設定した場合にAngularJSを使用します。ng-model属性が追加された場合、値は表示されません。

    <input type="text"
           id="rootFolder"
           ng-model="rootFolders"
           disabled="disabled"
           value="Bob"
           size="40"/>

この入力を何かにデフォルト設定してng-model?を保持する簡単な回避策を知っている人はいますか?ng-bindデフォルト値でaを使用しようとしましたが、それも機能しないようです。

回答:


223

これは望ましい動作です。モデルをビューではなくコントローラーで定義する必要があります。

<div ng-controller="Main">
  <input type="text" ng-model="rootFolders">
</div>


function Main($scope) {
  $scope.rootFolders = 'bob';
}

11
ありがとう。ただし、この場合、モデルはコントローラーに設定されます。そしてAngularのドキュメントでは、それは常に同じであり、データはコントローラに設定されます。しかし、私のコントローラーはJSファイルにあります。「編集」フォームでの操作方法は?デフォルトのフォームデータをコントローラーに「角度のある方法」で渡す方法は?
ByScripts 2013

8
これは私にとっては機能しませんが、Mark Rajcokが示す追加属性ng-init(ng-init = "rootFolders = 'Bob'")を追加すると正常に機能します。
Kaizar Laxmidhar 2014

また、<input type = "number" ng-model = "newTransaction [$ index] [user.email]" />のような入力フィールドがある場合、デフォルト値をどのように設定しますか?
シシ

188

Vojtaは "Angular way"について説明しましたが、本当にこれを機能させる必要がある場合は、@ urbanekが最近ng-initを使用して回避策を投稿しました。

<input type="text" ng-model="rootFolders" ng-init="rootFolders='Bob'" value="Bob">

https://groups.google.com/d/msg/angular/Hn3eztNHFXw/wk3HyOl9fhcJ


33
'value = "Bob"'の部分は必要ない場合があります。
Mark Rajcok

2
+1ですが、リンクされたディスカッションの投稿の1つで述べたように、それは回避する必要があります(論理的には正しくないため、テストが難しくなります)。
0xc0de 2013年

1
この方法は、v1.2でもモデル値を使用する場合に正常に機能します。<... ng-init = "rootFolders = someModelAttribute" ...>
dmcqu314

@ MarkRajcok、Stack OverflowにすばらしいAngularJS投稿がたくさんあります!あなたの洞察をSOコミュニティーと共有することに専念してきたすべての時間をありがとう。あなたが私たちを救ったすべての時間を心から感謝していると私が言うとき、私は多くの安心した開発者のために話すと確信しています!
Jeremy Moritz

1
それが私の問題を解決したので、マークの答えを本当に感謝します。value="Bob"inputタグにパーツが必要ないことを確認しました。
Devner 2014年

68

inputディレクティブをオーバーライドすることで、その仕事ができるようです。Dan Hunsakerのコードにいくつかの小さな変更を加えました。

  • $parse().assign()ngModel属性のないフィールドで使用する前にngModelのチェックを追加しました。
  • assign()関数のパラメーターの順序を修正しました。
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);
      }
    }
  };
});

これが私が見つけた最良の答えです!...私の問題をエレガントな方法で解決します。非表示の入力(サーバーで生成されたSymfonyフォームトークン)の値をキャプチャする必要がありました。
PachinSV 2014

これは賢いだけでなく、最善の解決策です。私の場合、PHPフォームであるため、コントローラーでng-modelのデフォルト値を設定できません。サーバー側の検証が失敗すると、フォームが更新され、ng-modelの内容はすべて失われ、入力値が削除されますあまりにも。
Luis Elizondo 2014

2
JavaScriptなしで動作するHTMLフォームの基本バージョンも必要な場合は、これが最良のソリューションのようです。
Darren

angular自体の中でデフォルトではない構成可能なオプションであるべき優れたソリューション。
Gracie

解決策をありがとう。数値入力の問題をどのように解決しますか?エラーdocs.angularjs.org/error/ngModel/numfmt?p0=20.12
mate.gwozdz

21

角度の方法

これを行う正しいAngularの方法は、フォームテンプレートに単一ページアプリAJAXを記述し、モデルから動的に入力することです。モデルは真実の唯一の情報源であるため、モデルはデフォルトではフォームから入力されません。代わりに、Angularは別の方法でモデルからフォームにデータを入力しようとします。

ただし、最初からやり直す時間がない場合

アプリを作成している場合は、かなり大きなアーキテクチャの変更が必要になる可能性があります。Angularを使用して既存のフォームを拡張しようとしている場合は、1ページのアプリ全体を最初から作成するのではなく、フォームから値をプルし、ディレクティブを使用してリンク時にスコープに保存できます。その後、Angularはスコープの値をフォームにバインドし、同期を保ちます。

ディレクティブを使用する

比較的単純なディレクティブを使用して、フォームから値をプルし、現在のスコープにロードできます。ここでは、initFromFormディレクティブを定義しました。

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

モデル名を取得するためにいくつかのフォールバックを定義したことがわかります。このディレクティブをngModelディレクティブと組み合わせて使用​​するか、必要に応じて$ scope以外のものにバインドできます。

次のように使用します。

<input name="test" ng-model="toaster.test" value="hello" init-from-form />
{{toaster.test}}

これはテキストエリアでも機能し、ドロップダウンを選択することに注意してください。

<textarea name="test" ng-model="toaster.test" init-from-form>hello</textarea>
{{toaster.test}}

これは、ここで説明されているものと同様のソリューションを実装するパックモジュールです。github.com/ platanus / angular
Agustin

1
優れたソリューションですが、でのみ機能しinput="text"ます。あなたが持っている場合、numberそれはスローされますモデルはタイプnumber docs.angularjs.org/error/ngModel/numfmt?p0=333
smoksnes

2
追加できる数値をサポートするため if (attrs.type === "number") val = parseInt(val);
smoksnes

@smoksnes-あなたは絶対に正しいです。私は答えを更新しました:)
16:19の

7

更新:私の元の答えには、コントローラーの使用がDOM対応のコードが含まれているため、Angularの慣習に違反してHTMLが使用されています。@dmackermanは私の回答のコメントでディレクティブに言及していましたが、今までそれを完全に逃しました。その入力で、これが正しい Angular または HTMLの規則に違反せずにこれを行う方法をます。


両方を取得する方法もあります。要素の値を取得し、それを使用してディレクティブのモデルを更新します。

<div ng-controller="Main">
    <input type="text" id="rootFolder" ng-model="rootFolders" disabled="disabled" value="Bob" size="40" />
</div>

その後:

app.directive('input', ['$parse', function ($parse) {
    return {
        restrict: 'E',
        require: '?ngModel',
        link: function (scope, element, attrs) {
            if(attrs.value) {
                $parse(attrs.ngModel).assign(scope, attrs.value);
            }
        }
    };
}]);

もちろん、上記のディレクティブを変更して、 value、モデルをその値に設定する前に属性を活用するます。たとえば$parse(attrs.value, scope)value属性をAngular式として扱うために使用することもできます(個人的には、そのために別の[カスタム]属性を使用します)したがって、標準のHTML属性は常に定数として扱われます)。

また、テンプレート化されたデータをng-modelで利用できるようにすることについても同様の質問があります。


コントローラーでDOM操作/検出を行うべきではありません。代わりにディレクティブを使用する必要があります。
dmackerman 2013

2
私は私の欠点でその欠点を明確に述べました。あなたはいけない、しかし、あなたはできます。それはすべて、Angularの慣習に従うかHTMLの慣習に従うことがより重要であるかによって異なります。AngularはHTMLを壊すからです。
Dan Hunsaker 2013年

3
ああ、私ダミーです。ディレクティブの使用については完全に見逃しました。それに応じて更新された回答。@dmackermanさん、あなたにとってジャークであることを心からお詫びします。
Dan Hunsaker、

ディレクティブをありがとう!私が取り組んでいるプロジェクトに適用して、サーバー側でコンテンツを生成し、それをクライアントのモデルとして使用する必要があるというアイデアが得られました。
ggalmazor 2014年

お役に立てて嬉しいです。もちろん、一般的に言えば、サーバーサイドのコンテンツをJSONとして構築し、それに基づいてアプリでモデルを操作する必要がありますが、他のオプションを使用すると便利な場合がありますが、これは1つに過ぎません。
Dan Hunsaker、2014年

7

AngularJs ngModelディレクティブを使用する場合、value属性の値はngModelフィールドにバインドされないことに注意してください。自分で初期化する必要があり、それを行う最善の方法は、

<input type="text"
       id="rootFolder"
       ng-init="rootFolders = 'Bob'"
       ng-model="rootFolders"
       disabled="disabled"
       value="Bob"
       size="40"/>

コントローラではなくディレクティブ/マークアップでそれを初期化するのは奇妙に感じます。
random_user_name 2016

5

これは以前の回答を少し変更したものです...

$ parseは必要ありません

angular.directive('input', [function () {
  'use strict';

  var directiveDefinitionObject = {
    restrict: 'E',
    require: '?ngModel',
    link: function postLink(scope, iElement, iAttrs, ngModelController) {
      if (iAttrs.value && ngModelController) {
        ngModelController.$setViewValue(iAttrs.value);
      }
    }
  };

  return directiveDefinitionObject;
}]);

ngModelController。$ setViewValueはモデルの状態をダーティに変更し、初期状態をfalseに変更しますが、フォームの状態にも影響を及ぼし、しばらくの間は痛みを伴う可能性があることに注意してください。
Atul Chaudhary、2015年

2

こんにちはモデルの初期化で以下のメソッドを試すことができます。

ここでは、テキストボックスのngモデルを2つの方法で初期化できます

-ng-initを使用

-jsで$ scopeを使用

<!doctype html>
 <html >
 <head>
        <title>Angular js initalize with ng-init and scope</title>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
</head>
<body ng-app="app" >
    <h3>Initialize value with ng-init</h3>
    <!-- Initlialize model values with ng-init -->
    <div ng-init="user={fullname:'Bhaskar Bhatt',email:'bhatt.bhaskar88@gmail.com',address:'Ahmedabad'};">
        Name : <input type="text" ng-model="user.fullname" /><br/>
        Email : <input type="text" ng-model="user.email" /><br/>
        Address:<input type="text" ng-model="user.address" /><br/>

    </div>  
    <!-- initialize with js controller scope -->
    <h3>Initialize with js controller</h3>

    <div  ng-controller="alpha">
        Age:<input type="text" name="age" ng-model="user.age" /><br/>
        Experience : <input type="text" name="experience" ng-model="user.exp" /><br/>
        Skills : <input type="text" name="skills" ng-model="user.skills" /><br/>
    </div>  

</body> 
<script type="text/javascript">
        angular.module("app",[])
        .controller("alpha",function($scope){
            $scope.user={};
            $scope.user.age=27;
            $scope.user.exp="4+ years";
            $scope.user.skills="Php,javascript,Jquery,Ajax,Mysql";
        });

     </script>
 </html>                

0

問題は、ng-value / valueを設定する場所の親要素にng-modelを設定する必要があることです。Angularが述べたように:

これは主にinput [radio]およびoption要素で使用されるため、要素が選択されると、その要素(またはその選択親要素)のngModelがバインドされた値に設定されます。

例:これは実行されたコードです:

<div class="col-xs-12 select-checkbox" >
<label style="width: 18em;" ng-model="vm.settingsObj.MarketPeers">
  <input name="radioClick" type="radio"  ng-click="vm.setPeerGrp('market');" 
         ng-value="vm.settingsObj.MarketPeers" 
         style="position:absolute;margin-left: 9px;">
  <div style="margin-left: 35px;color: #717171e8;border-bottom: 0.5px solid #e2e2e2;padding-bottom: 2%;">Hello World</div>
</label>
</div>

注:この上記のケースでは、ng-modelとその値に対するJSON応答がすでにあったため、JSオブジェクトに "MarketPeers"として別のプロパティを追加しています。したがって、モデルと値は必要に応じて異なる可能性がありますが、ng-modelとvalueの両方を持ち、同じ要素にそれらを持たないようにすることで、このプロセスは役立つと思います。


0

同様の問題がありました。を使用value="something"して表示および編集することができませんでした。<input>宣言されているモデルとともに、以下のコマンドを使用する必要がありました。

[(ngModel)]=userDataToPass.pinCode

オブジェクト内のデータのリストuserDataToPassと、表示および編集する必要があるアイテムはどこにありますかpinCode

同じように、私はこのYouTubeビデオを参照しました


このHOWTOのために、OPはAngularJSを使用している、あなたのYTのビデオ・リファレンスは角度4.使用している
Chris22
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.