ng-changeで選択されたng-objectを取得する


313

次の選択要素があるとします

<select ng-options="size.code as size.name for size in sizes " 
        ng-model="item.size.code" 
        ng-change="update(MAGIC_THING)">
</select>

私はへのアクセスを持っているのでMAGIC_THINGは、現在選択されているサイズと同じになるように取得する方法はありsize.namesize.code私のコントローラには?

size.codeは、アプリの他の部分(画像のURLなど)の多くに影響しますが、ngのモデル時にitem.size.code更新されるが、item.size.name必要なものが直面しているユーザーに対しても同様に更新されます。これを行う正しい方法は、変更イベントをキャプチャしてコントローラー内の値を設定することだと思いますが、適切な値を取得するためにupdateに何を渡せるかわかりません。

これがそれについて完全に間違った方法であるなら、私は正しい方法を知りたいです。

回答:


488

ng-modelをitem.size.codeに設定する代わりに、それをsizeに設定するのはどうですか:

<select ng-options="size as size.name for size in sizes" 
   ng-model="item" ng-change="update()"></select>

次に、update()メソッドで$scope.item、現在選択されている項目に設定されます。

そしてitem.size.code、必要なコードが何であれ、経由でそのプロパティを取得できます$scope.item.code

フィドル

コメントの詳細情報に基づいて更新

次に、選択したng-modelに他の$ scopeプロパティを使用します。

<select ng-options="size as size.name for size in sizes" 
   ng-model="selectedItem" ng-change="update()"></select>

コントローラ:

$scope.update = function() {
   $scope.item.size.code = $scope.selectedItem.code
   // use $scope.selectedItem.code and $scope.selectedItem.name here
   // for other stuff ...
}

1
モデルをアイテムとして設定した場合、値を事前選択するにはどうすればよいですか?
Patrick

5
これをyour <select>ng-init = "item = sizes [0]"の中に入れます
Mark Rajcok

どうもありがとうございましたが、十分な状況を共有できていないと思います。itemは、ページの読み込み時に作成されるオブジェクトです。オブジェクトのサイズ配列は、ユーザーが編集ボタンを操作すると表示されるため、これを実行すると、アイテムオブジェクト全体がオーバーライドされます。データオブジェクトの完全に別の部分から値を事前選択する選択ボックスに一連のオプションを作成する方法が必要です。
Patrick

14
これは本当ですか?ng-modelが更新される前にng-changeハンドラーが起動されるようですので、$ scope.item.size.code = $ scope.selectedItem.codeを試行しても、更新されたモデル値が常に提供されるとは限りません。ng-changeを使用しているときに誰かがそれを見たことがありますか?
Karl

6
これを行うのを妨げるものは何もないと思います:ng-model="selectedItem" ng-change="update(selectedItem)"
Rhys van der Waerden 2014年

52

次のコードを使用して、選択した値を直接取得することもできます

 <select ng-options='t.name for t in templates'
                  ng-change='selectedTemplate(t.url)'></select>

script.js

 $scope.selectedTemplate = function(pTemplate) {
    //Your logic
    alert('Template Url is : '+pTemplate);
}

5
これは、受け入れられたものが代替案を与える一方で、質問に答えます
redben

1
テンプレート変数をどこで初期化または取得しますか?
Kat Lim Ruiz

29
これはモデルを指定せずに機能しますか?このエラーが発生します:ディレクティブ 'select'で必要なコントローラー 'ngModel'が見つかりません!
2014年

8
ドキュメントによると、ngModelは確実に一部の要素に必要です。他のディレクティブはオプションですが、それは必須ではありません。
mnemia 14

26
これは動作しません!ng-changeは、ng-options内で作成された一時変数(t)にアクセスできません。
ガベージ

16

あなたもこれを試すことができます:

<select  ng-model="selectedItem" ng-change="update()">
<option ng-repeat="item in items" ng-selected="selectedItem == item.Id" value="{{item.Id}}">{{item.Name}}</option>
</select>

2
このソリューションは、値をフォーマットする必要がある場合に適しています。Selectアプローチだけでは、値を簡単にフォーマットできませんでした。
mbokil

7

Divyesh Rupawalaの答えが機能しない(現在のアイテムをパラメーターとして渡す)場合はonChanged()、このPlunkerの関数を参照してください。それは使用していthisます:

http://plnkr.co/edit/B5TDQJ


2
<select ng-model="item.size.code">
<option ng-repeat="size in sizes" ng-attr-value="size.code">{{size.name}}          </option>
</select>

11
選択でng-repeatの代わりにng-optionsを使用します。
Jepser Bernardino 2014

12
@JepserBernardinoでは、<option>へのより細かいアクセスが必要になる場合があります。たとえば、特別なオプションやデフォルトのオプションが選択されているかどうかに関係なくスタイルを設定するには
Ekus

2

//Javascript
$scope.update = function () {
    $scope.myItem;
    alert('Hello');
}
<!--HTML-->
<div class="form-group">
     <select name="name"
             id="id" 
             ng-model="myItem" 
             ng-options="size as size.name for size in sizes"
             class="form-control" 
             ng-change="update()"
             multiple
             required>
     </select>
</div>

書きたい名前、名前、ID、クラス、複数、必須、このように書くことができます。


1

これはあなたにいくつかのアイデアを与えるかもしれません

.NET C#ビューモデル

public class DepartmentViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
}

.NET C#Web Apiコントローラー

public class DepartmentController : BaseApiController
{
    [HttpGet]
    public HttpResponseMessage Get()
    {
        var sms = Ctx.Departments;

        var vms = new List<DepartmentViewModel>();

        foreach (var sm in sms)
        {
            var vm = new DepartmentViewModel()
            {
                Id = sm.Id,
                Name = sm.DepartmentName
            };
            vms.Add(vm);
        }

        return Request.CreateResponse(HttpStatusCode.OK, vms);
    }

}

角度コントローラー:

$http.get('/api/department').then(
    function (response) {
        $scope.departments = response.data;
    },
    function (response) {
        toaster.pop('error', "Error", "An unexpected error occurred.");
    }
);

$http.get('/api/getTravelerInformation', { params: { id: $routeParams.userKey } }).then(
   function (response) {
       $scope.request = response.data;
       $scope.travelerDepartment = underscoreService.findWhere($scope.departments, { Id: $scope.request.TravelerDepartmentId });
   },
    function (response) {
        toaster.pop('error', "Error", "An unexpected error occurred.");
    }
);

角度テンプレート:

<div class="form-group">
    <label>Department</label>
    <div class="left-inner-addon">
        <i class="glyphicon glyphicon-hand-up"></i>
        <select ng-model="travelerDepartment"
                ng-options="department.Name for department in departments track by department.Id"
                ng-init="request.TravelerDepartmentId = travelerDepartment.Id"
                ng-change="request.TravelerDepartmentId = travelerDepartment.Id"
                class="form-control">
            <option value=""></option>
        </select>
    </div>
</div>

1

オブジェクトを正しく比較できるように、「追跡」を使用する必要があります。それ以外の場合、Angularはネイティブjsの方法でオブジェクトを比較します。

したがって、コード例は次のようになります-

    <select ng-options="size.code as size.name
 for size in sizes track by size.code" 
ng-model="item.size.code"></select>

1

AngularJSのフィルターがうまく機能しました。

code/iduniqueであると仮定すると、AngularJSを使用してその特定のオブジェクトを除外filterし、選択したオブジェクトのプロパティを操作できます。上記の例を考えてみましょう:

<select ng-options="size.code as size.name for size in sizes" 
        ng-model="item.size.code" 
        ng-change="update(MAGIC_THING); search.code = item.size.code">
</select>

<!-- OUTSIDE THE SELECT BOX -->

<h1 ng-repeat="size in sizes | filter:search:true"
    ng-init="search.code = item.size.code">
  {{size.name}}
</h1>

これには、3つの重要な側面があります

  1. ng-init="search.code = item.size.code"- ボックスh1外の要素を初期化selectする際に、フィルタークエリを選択したオプションに設定します

  2. ng-change="update(MAGIC_THING); search.code = item.size.code"-選択入力を変更すると、「検索」クエリを現在選択されているに設定する1行が実行されitem.size.codeます。

  3. filter:search:true- trueフィルターに渡して、厳密な一致を有効にします。

それでおしまい。size.codeuniqueIDの場合、h1テキストがの要素は1つだけになりますsize.name

私は自分のプロジェクトでこれをテストしましたが、うまくいきます。

幸運を


0

これは、角度選択オプションリスト(IdまたはText以外)から値を取得する最もクリーンな方法です。あなたのページに次のような製品選択があると仮定します:

<select ng-model="data.ProductId"
        ng-options="product.Id as product.Name for product in productsList"
        ng-change="onSelectChange()">
</select>

次に、コントローラーでコールバック関数を次のように設定します。

    $scope.onSelectChange = function () {
        var filteredData = $scope.productsList.filter(function (response) {
            return response.Id === $scope.data.ProductId;
        })
        console.log(filteredData[0].ProductColor);
    }

簡単に説明すると、ng-changeイベントはselectのオプション項目を認識しないため、ngModelを使用して、コントローラーに読み込まれたオプションリストから選択された項目をフィルターで除外しています。

さらに、ngModelが実際に更新される前にイベントが発生するため、望ましくない結果が得られる可能性があるため、タイムアウトを追加することをお勧めします。

        $scope.onSelectChange = function () {
            $timeout(function () {
            var filteredData = $scope.productsList.filter(function (response) {
                return response.Id === $scope.data.ProductId;
            })
            console.log(filteredData[0].ProductColor);
            }, 100);
        };
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.