ng-modelを動的に割り当てる


82

オブジェクト配列から一連のチェックボックスを生成しようとしています。チェックボックスで、ng-modelを配列に送信される新しいオブジェクトのプロパティに動的にマップすることを目指しています。

私が考えていたのは

<li ng-repeat="item in items">
    <label>{{item.name}}</label>
    <input type="checkbox" ng-model="newObject.{{item.name}}">
</li>

このJSFiddleで見られるように、これは機能しません。

http://jsfiddle.net/GreenGeorge/NKjXB/2/

誰か助けてもらえますか?

回答:


146

これにより、望ましい結果が得られるはずです。

<input type="checkbox" ng-model="newObject[item.name]">

これが機能するプランクです:http://plnkr.co/edit/ALHQtkjiUDzZVtTfLIOR?p = Preview


1
うーん、実際これは文字通り私に '<input ng-model = "newObject [item.name]">'を与えました、それは何か足りないものですか?
ジョージアナンダエマン2013年

うーん、奇妙なことに、ライブの例を追加しました(何らかの理由でjsFiddleが今日私の側で機能していないため、プランカー)。
pkozlowski.opensource 2013年

ああ、はい、私はphpで考えることに慣れていて、実際のマークアップが名前に変わることを期待していました、それはうまくいきました。どうも!
ジョージアナンダエマン2013年

2
素晴らしい、まさに私が探していたもの。Angularが大好きです!
SharkofMirkwood 2013年

1
Angular 2でもうまく機能します。しかし、多次元オブジェクトのソリューションもありますか?あなたの例では、ifitem.nameは時々を指しnewObject['x']、時にはを指す必要がありますnewObject['x']['y']
マルティン・シュナイダー

23

編集 これをng-changeで使用するコメントに正しく記載されているように、「ダミー」のng-modelが事前に存在している必要があります。ただし、明らかに1.3では、必要なオプションがフレームワークによって提供されていることに注意してください。以下のhttps://stackoverflow.com/a/28365515/3497830をチェックしてください/編集

より複雑なタスクを実行しているときに単純なケースに遭遇した場合に備えて、これは、任意の式をng-modelに動的にバインドするために私が思いついたソリューションです。 http //plnkr.co/edit/ccdJTm0zBnqjntEQfAfx?p =プレビュー

方法:標準の角度式を受け取り、それを評価し、ng-modelと$ compileを介して結果をスコープにリンクするディレクティブdynamicModelを作成しました。

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.data = {};
  $scope.testvalue = 'data.foo';
  $scope.eval = $scope.$eval;
});

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.data = {};
  $scope.testvalue = 'data.foo';
  $scope.eval = $scope.$eval;
});

app.directive('dynamicModel', ['$compile', function ($compile) {
    return {
        'link': function(scope, element, attrs) {
            scope.$watch(attrs.dynamicModel, function(dynamicModel) {
                if (attrs.ngModel == dynamicModel || !dynamicModel) return;

                element.attr('ng-model', dynamicModel);
                if (dynamicModel == '') {
                    element.removeAttr('ng-model');
                }

                // Unbind all previous event handlers, this is 
                // necessary to remove previously linked models.
                element.unbind();
                $compile(element)(scope);
            });
        }
    };
}]);

使用法は単純にdynamic-model = "angularExpression"であり、angularExpressionは、ng-modelの式として使用される文字列になります。

これにより、このソリューションを考え出す必要があるという頭痛の種が軽減されることを願っています。

よろしく、ジャスタス


3
あなたは命の恩人です。私はこの投稿を見つける前にほとんど絶望していました。
Nelo Mitranim 2014

ブライアンをもっと具体的にできますか?何を試し、何が起こったのですか?
Justus Wingert 2014

これは、ソリューションの競争の宝石です。あなたは私を非常に厄介な問題から解放しました-ありがとう!
Mikebert4 2015

1
ng-changeはこれでは機能しません。角度ソースを見ると、ngChangeディレクティブには必須ディレクティブとしてngModelがあります。クイック検索では、ngChangeとngListのみにこの問題があることが示されています。他のすべてのディレクティブには、オプションのコントローラーとしてngModelがあるようです。dynamic-modelディレクティブを使用して任意の要素にng-model = "dummyValue"を追加することにより、この問題を回避しました。動的モデルへの変更は$ compileを呼び出すため、ngChangeおよびng-model値を使用するその他のディレクティブは正しく更新されます。
EverPresent 2015年

1
これは、動的モデルの値の変化を監視する必要がない場合の、より堅牢なソリューションです-stackoverflow.com/a/32096328/887092
Todd

6

Angular 1.3では、ng-model-optionsディレクティブを使用してモデルを動的に割り当てたり、式にバインドしたりできます。

ここにプランカーがあります:http://plnkr.co/edit/65EBiySUc1iWCWG6Ov98?p = Preview

<input type="text" ng-model="name"><br>
<input type="text" ng-model="user.name" 
ng-model-options="{ getterSetter: true }">

詳細については、httpsngModelOptions//docs.angularjs.org/api/ng/directive/ngModelOptionsをご覧ください。


何かが足りない場合はご容赦ください。ただし、動的なモデル割り当てが含まれているように見えるものはありません。そして、ngModelOptionsについては明らかにそれをサポートしません。明確にできますか?実際、そのように機能すれば非常に便利になるからです...
XML

@XMLilley "getterSetter:ngModelにバインドされた関数をゲッター/セッターとして扱うかどうかを決定するブール値。"
クリスボルトン

これを私の注意を引いてくれたRobに感謝します。私は私の答えを更新し、あなたの答えにリンクしました。
Justus Wingert 2015年

1

これは、より深い表現をサポートするための私のアプローチです。例: 'model.level1.level2.value'

<input class="form-control" ng-model="Utility.safePath(model, item.modelPath).value">

ここで、item.modelPath = 'level1.level2'およびUtility(model、 'level1.level2')は、model.level1.level2を返すユーティリティ関数です。


これがどのように機能するかについて詳しく説明していただけますか?Utility.safePathは、.valueを使用できるように何を返しますか?
デボンホルコム2017年

Utility.safePathは、パス文字列で指定されたネストされた変数の値を返します。たとえば、level1.level2はmodel.level1.level2を参照します。
Kanit Mekritthikrai 2018年

0

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>

    <div ng-app="myApp" ng-controller="myCtrl">
        <form name="priceForm" ng-submit="submitPriceForm()">
            <div ng-repeat="x in [].constructor(9) track by $index">
                <label>
                    Person {{$index+1}} <span class="warning-text">*</span>
                </label>
                <input type="number" class="form-control" name="person{{$index+1}}" ng-model="price['person'+($index+1)]" />

            </div>
            <button>Save</button>
        </form>
    </div>

    <script>
        var app = angular.module('myApp', []);
        app.controller('myCtrl', function ($scope) {
            $scope.price = [];
            $scope.submitPriceForm = function () {
                //objects be like $scope.price=[{person1:value},{person2:value}....]
                console.log($scope.price);
            }
        });
    </script>
</body>
</html>

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.