การรับ ng-object ที่ถูกเลือกด้วย ng-change


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.nameและsize.codeควบคุมได้หรือไม่?

size.code มีผลต่อส่วนอื่น ๆ ของแอป (URL รูปภาพ ฯลฯ ) แต่เมื่อitem.size.codeมีการอัปเดตรูปแบบ ng item.size.nameจะต้องได้รับการอัปเดตเช่นกันสำหรับผู้ใช้ที่กำลังเผชิญกับสิ่งต่าง ๆ ฉันคิดว่าวิธีที่ถูกต้องในการทำเช่นนี้คือการบันทึกเหตุการณ์การเปลี่ยนแปลงและการตั้งค่าภายในคอนโทรลเลอร์ของฉัน แต่ฉันไม่แน่ใจว่าฉันจะส่งผ่านการอัปเดตเพื่อรับค่าที่เหมาะสมได้อย่างไร

หากนี่เป็นวิธีที่ผิดไปโดยสิ้นเชิงฉันชอบที่จะรู้วิธีที่ถูกต้อง

คำตอบ:


488

แทนที่จะตั้งค่า ng-model เป็น item.size.code วิธีการตั้งค่าเป็นขนาด:

<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

ซอ

อัปเดตตามข้อมูลเพิ่มเติมในความคิดเห็น:

ใช้คุณสมบัติ $ scope อื่น ๆ สำหรับ ng-model ที่คุณเลือกแล้ว:

<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
หากฉันตั้งค่าแบบจำลองของฉันเป็นรายการฉันจะเลือกค่าล่วงหน้าได้อย่างไร
แพทริค

5
ใส่สิ่งนี้ไว้ใน<select>: ng-init = "item = sizes [0]"
Mark Rajcok

ขอบคุณมากสำหรับความช่วยเหลือของคุณ แต่ฉันไม่คิดว่าฉันจะแบ่งปันสถานการณ์ให้เพียงพอ item เป็นวัตถุที่สร้างการโหลดหน้าเว็บ อาร์เรย์ขนาดของวัตถุมาในการโต้ตอบกับผู้ใช้ด้วยปุ่มแก้ไขดังนั้นถ้าฉันทำเช่นนี้มันจะแทนที่วัตถุรายการทั้งหมด ฉันต้องการวิธีในการสร้างตัวเลือกมากมายในกล่องเลือกที่เลือกค่าล่วงหน้าจากส่วนข้อมูลแยกต่างหากอย่างสมบูรณ์
แพทริค

14
มันเป็นเรื่องจริงเหรอ? ดูเหมือนว่าตัวจัดการการเปลี่ยนแปลง ng จะเริ่มทำงานก่อนที่จะอัปเดต ng-model ดังนั้นให้ลองใช้ $ scope.item.size.code = $ scope.selectedItem.code อาจไม่ให้ค่ารุ่นที่ปรับปรุงแล้วเสมอ มีใครเห็นว่าเมื่อใช้ NG-Change?
Karl

6
คิดว่าไม่มีอะไรหยุดคุณจากการทำเช่นนี้:ng-model="selectedItem" ng-change="update(selectedItem)"
Rhys van der Waerden

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
ใช้งานได้โดยไม่ระบุรุ่นหรือไม่ ฉันได้รับข้อผิดพลาดนี้: คอนโทรลเลอร์ 'ngModel', ต้องการโดย directive 'select', ไม่พบ!
fer

8
จำเป็นต้องมี ngModel สำหรับองค์ประกอบที่เลือกตามเอกสาร คำสั่งอื่นเป็นทางเลือก แต่ไม่ได้มีคำสั่ง
mnemia

26
มันไม่ทำงาน! ng-change ไม่สามารถเข้าถึงตัวแปรชั่วคราว (t) ที่สร้างขึ้นภายใน ng-options
ขยะ

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
วิธีนี้เป็นวิธีที่ดีถ้าคุณต้องการจัดรูปแบบค่า ใช้เพียงวิธีเลือกฉันไม่สามารถจัดรูปแบบค่าได้อย่างง่ายดาย
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-options แทน ng-repeat ในการเลือก
Jepser Bernardino

12
@JepserBernardino บางครั้งคุณจำเป็นต้องเข้าถึง <option> อย่างละเอียดยิ่งขึ้นเพื่อจัดรูปแบบตัวเลือกพิเศษ / ค่าเริ่มต้นโดยไม่คำนึงว่าพวกเขาจะถูกเลือกหรือไม่
30904 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 # View Model

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

.NET C # Web Api Controller

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/idเป็นเอกลักษณ์เราสามารถกรองวัตถุนั้นด้วย 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"- เมื่อคุณเปลี่ยนเลือกอินพุตเราจะทำงานสายอีกหนึ่งซึ่งจะตั้ง "ค้นหา" item.size.codeแบบสอบถามเพื่อเลือกในขณะนี้

  3. filter:search:true- ผ่านtrueการกรองเพื่อเปิดใช้งานการจับคู่ที่เข้มงวด

แค่นั้นแหละ. ถ้าsize.codeเป็นUniqueIDเราจะมีเพียงหนึ่งองค์ประกอบที่มีข้อความของh1size.name

ฉันได้ทดสอบสิ่งนี้ในโครงการแล้วและใช้งานได้

โชคดี


0

นี่เป็นวิธีที่สะอาดที่สุดในการรับค่าจากรายการตัวเลือกการเลือกเชิงมุม (นอกเหนือจาก The 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 ไม่รู้จักรายการตัวเลือกในการเลือกเราจึงใช้ 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.