[javascript] كيف يمكنني تعيين خاصية القيمة في خيارات ng AngularJS '؟



Answers

كيف تحصل سمات القيمة على قيمتها:

  • عند استخدام مصفوفة كمصدر بيانات ، سيكون فهرس عنصر الصفيف في كل تكرار ؛
  • عند استخدام كائن كمصدر بيانات ، سيكون اسم الخاصية في كل عملية تكرار.

لذا في حالتك ، يجب أن يكون:

obj = { '1': '1st', '2': '2nd' };

<select ng-options="k as v for (k,v) in obj"></select>
Question

هنا هو ما يبدو أن يزعج الكثير من الناس (بما في ذلك لي).

عند استخدام توجيه ng-options في AngularJS لملء الخيارات الخاصة بعلامة <select> ، لا يمكنني معرفة كيفية تعيين قيمة لأحد الخيارات. وثائق هذا غير واضحة - على الأقل بالنسبة لشخصية بسيطة مثلي.

يمكنني تعيين النص لأحد الخيارات بسهولة مثل:

ng-options="select p.text for p in resultOptions"

عندما تكون resultOptions على سبيل المثال:

[
    {
        "value": 1,
        "text": "1st"
    },
    {
        "value": 2,
        "text": "2nd"
    }
]

يجب أن يكون (وربما هو) أبسط شيء لتعيين قيم الخيارات ، ولكن حتى الآن لا أفهم.




شغّل مقتطف الشفرة وشاهد الأشكال. هنا هو ملاحظة لفهم سريع

  1. مثال 1 (اختيار الكائن): - ng-option="os.name for os in osList track by os.id" . هنا من track by os.id مهم وينبغي أن يكون هناك و os.id as لا ينبغي أن يكون قبل os.name .

    • يجب تعيين ng-model="my_os" على كائن به مفتاح my_os={id: 2} مثل my_os={id: 2} .
  2. المثال 2 (تحديد القيمة): - ng-option="os.id as os.name for os in osList" . هنا لا ينبغي أن يكون track by os.id هناك و os.id as ينبغي أن يكون هناك قبل os.name .

    • يجب تعيين ng-model="my_os" على قيمة مثل my_os= 2

سوف يشرح مقتطف رمز الراحة.

angular.module('app', []).controller('ctrl', function($scope, $timeout){
  
  //************ EXAMPLE 1 *******************
  $scope.osList =[
    { id: 1, name :'iOS'},
    { id: 2, name :'Android'},
    { id: 3, name :'Windows'}
  ]
  $scope.my_os = {id: 2};
  
  
  //************ EXAMPLE 2 *******************
  $timeout(function(){
    $scope.siteList = [
          { id: 1, name: 'Google'},
          { id: 2, name: 'Yahoo'},
          { id: 3, name: 'Bing'}
        ];
   }, 1000);
    
    $scope.my_site = 2;
  
    $timeout(function(){
      $scope.my_site = 3;
    }, 2000);
})
fieldset{
  margin-bottom: 40px;
  }
strong{
  color:red;
  }
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.10/angular.min.js"></script>

<div ng-app="app" ng-controller="ctrl">

  <!--//************ EXAMPLE 1 *******************-->
  <fieldset>
    <legend>Example 1 (Set selection as <strong>object</strong>)</legend>
    
    <select ng-model="my_os" ng-options="os.name for os in osList track by os.id">
        <option value="">--Select--</option>
      </select>
    {{my_os}}
    
  </fieldset>
  
  
  <!--//************ EXAMPLE 2 *******************-->
  <fieldset>
    <legend>Example 2 (Set selection as <strong>value</strong>. Simulate ajax)</legend>
      <select ng-model="my_site" ng-options="site.id as site.name for site in siteList">
        <option value="">--Select--</option>
      </select>
      {{my_site}}
  </fieldset>
  
</div>




تم توفير الإجابة الصحيحة لهذا السؤال من قِبل المستخدم frm.adiputra ، حيث يبدو أن هذه هي الطريقة الوحيدة للتحكم صراحة في خاصية القيمة لعناصر الخيار.

ومع ذلك ، أردت فقط التأكيد على أن "select" ليست كلمة رئيسية في هذا السياق ، ولكنها مجرد عنصر نائب للتعبير. يرجى الرجوع إلى القائمة التالية ، لتعريف تعبير "select" بالإضافة إلى تعبيرات أخرى يمكن استخدامها في توجيه ng-options.

استخدام الاختيار كما هو مبين في السؤال:

ng-options='select p.text for p  in resultOptions'

خطأ جوهري

استنادًا إلى قائمة التعبيرات ، يبدو أنه يمكن استخدام trackexpr لتحديد القيمة ، عندما يتم عرض الخيارات في مجموعة من الكائنات ، ولكن تم استخدامها مع التجميع فقط.

من وثائق AngularJS "للحصول على خيارات ng:

  • مصفوفة / كائن : تعبير يتم تقييمه إلى مصفوفة / كائن لتكرارها.
  • value : المتغير المحلي الذي سيشير إلى كل عنصر في الصفيف أو كل قيمة خاصية للكائن أثناء التكرار.
  • المفتاح : متغير محلي سيشير إلى اسم خاصية في الكائن أثناء التكرار.
  • label : ستكون نتيجة هذا التعبير التسمية للعنصر. من المرجح أن يشير التعبير إلى متغير القيمة (على سبيل المثال ، value.propertyName).
  • select : ستكون نتيجة هذا التعبير مرتبطة بنموذج العنصر الرئيسي. إذا لم يتم تحديده ، فسيؤدي تحديد التعبير إلى القيمة الافتراضية.
  • group : سيتم استخدام نتيجة هذا التعبير لتجميع الخيارات باستخدام عنصر DOM.
  • trackexpr : يستخدم عند العمل مع مجموعة من الكائنات. سيتم استخدام نتيجة هذا التعبير لتحديد الكائنات الموجودة في الصفيف. من المرجح أن يشير trackexpr إلى متغير القيمة (مثل value.propertyName).



ساعد البرنامج التعليمي ANGULAR.JS: NG-SELECT و NG-OPTIONS على حل المشكلة:

<select id="countryId"
  class="form-control"
  data-ng-model="entity.countryId"
  ng-options="value.dataValue as value.dataText group by value.group for value in countries"></select>



يبدو أن ng-options معقدة (ربما محبطة) لاستخدامها ، ولكن في الواقع لدينا مشكلة في الهندسة المعمارية.

AngularJS بمثابة إطار MVC لتطبيق HTML + جافا سكريبت ديناميكي. في حين أن المكون (V) iew الخاص به يقدم HTML "templating ،" هدفه الأساسي هو ربط إجراءات المستخدم ، عن طريق وحدة تحكم ، بالتغييرات في النموذج. لذلك ، فإن المستوى المناسب من التجريد ، والذي من خلاله يعمل في AngularJS ، هو أن عنصر التحديد يحدد قيمة في النموذج لقيمة من استعلام .

  • كيف يتم تقديم صف الاستعلام للمستخدم هو قلق (V) iew و ng-options يوفر للكلمة المفتاحية أن تحدد ما هي محتويات عنصر الخيار مثل p.text for p in resultOptions .
  • كيف يتم تقديم صف محدد للخادم هو قلق (M) odel. لذلك ng-options توفر ng-options كلمة أساسية لتحديد القيمة التي يتم توفيرها للنموذج كما في k as v for (k,v) in objects .

الحل الصحيح هذه المشكلة هو ثم الهندسة المعمارية في الطبيعة ، وينطوي على إعادة بناء HTML الخاص بك بحيث ينفذ (M) odel اتصالات الخادم عند الحاجة (بدلاً من المستخدم إرسال نموذج).

إذا كانت صفحة MVC HTML عبارة عن over-engineering غير ضروري للمشكلة في متناول اليد: ثم استخدم الجزء الخاص بتوليد HTML فقط لمكون iew في AngularJS (V). في هذه الحالة ، اتبع نفس النمط المستخدم في إنشاء عناصر مثل &lt;li /&gt; تحت &lt;ul /&gt; وكرر نانوغرام على عنصر خيار:

<select name=“value”>
    <option ng-repeat=“value in Model.Values” value=“{{value.value}}”>
        {{value.text}}
    </option>
</select>

وباعتباره kludge ، يمكن للمرء دائمًا نقل سمة الاسم لعنصر select إلى عنصر إدخال مخفي:

<select ng-model=“selectedValue” ng-options=“value.text for value in Model.Values”>
</select>
<input type=“hidden” name=“value” value=“{{selectedValue}}” />



لقد ناضلت مع هذه المشكلة لفترة من الوقت اليوم. قرأت من خلال وثائق AngularJS ، هذا ومشاركات أخرى وعدد قليل من بلوق أنها تؤدي إلى. لقد ساعدوني جميعًا على تفصيل التفاصيل الدقيقة ، ولكن في النهاية يبدو هذا موضوعًا محيرًا. ويرجع ذلك أساسا إلى العديد من الفروق الدقيقة النحوية ng-options .

في النهاية ، بالنسبة لي ، انخفض إلى أقل هو أكثر من ذلك.

بالنظر إلى نطاق تم تكوينه على النحو التالي:

        //Data used to populate the dropdown list
        $scope.list = [
           {"FirmnessID":1,"Description":"Soft","Value":1},         
           {"FirmnessID":2,"Description":"Medium-Soft","Value":2},
           {"FirmnessID":3,"Description":"Medium","Value":3}, 
           {"FirmnessID":4,"Description":"Firm","Value":4},     
           {"FirmnessID":5,"Description":"Very Firm","Value":5}];

        //A record or row of data that is to be save to our data store.
        //FirmnessID is a foreign key to the list specified above.
        $scope.rec = {
           "id": 1,
           "FirmnessID": 2
        };

هذا هو كل ما أحتاجه للحصول على النتيجة المرجوة:

        <select ng-model="rec.FirmnessID"
                ng-options="g.FirmnessID as g.Description for g in list">
            <option></option>
        </select>   

لاحظ أنني لم أستخدم track by . يؤدي استخدام track by العنصر المحدد دائمًا إلى إرجاع الكائن المطابق لـ FirmnessID ، بدلاً من FirmnessID نفسه. يفي هذا الآن بمعاييري ، وهو أنه يجب أن يعرض قيمة رقمية بدلاً من الكائن ، وأن يستخدم ng-options للحصول على تحسين الأداء الذي يوفره عن طريق عدم إنشاء نطاق جديد لكل خيار يتم إنشاؤه.

أيضا ، كنت بحاجة إلى الصف الأول الفارغ ، لذلك أضفت ببساطة <option> إلى العنصر <select> .

هنا هو Plunkr الذي يظهر عملي.




بالنسبة لي ، فإن إجابة برونو غوميز هي أفضل إجابة.

ولكن في الواقع ، لا داعي للقلق بشأن تعيين خاصية القيمة لخيارات الاختيار. سوف AngularJS الاعتناء بذلك. اسمحوا لي أن أشرح بالتفصيل.

يرجى النظر في هذا الكمان

angular.module('mySettings', []).controller('appSettingsCtrl', function ($scope) {

    $scope.timeFormatTemplates = [{
        label: "Seconds",
        value: 'ss'
    }, {
        label: "Minutes",
        value: 'mm'
    }, {
        label: "Hours",
        value: 'hh'
    }];


    $scope.inactivity_settings = {
        status: false,
        inactive_time: 60 * 5 * 3, // 15 min (default value), that is, 900 seconds
        //time_format: 'ss', // Second (default value)
        time_format: $scope.timeFormatTemplates[0], // Default seconds object
    };

    $scope.activity_settings = {
        status: false,
        active_time: 60 * 5 * 3, // 15 min (default value), that is,  900 seconds
        //time_format: 'ss', // Second (default value)
        time_format: $scope.timeFormatTemplates[0], // Default seconds object
    };

    $scope.changedTimeFormat = function (time_format) {
        'use strict';

        console.log('time changed');
        console.log(time_format);
        var newValue = time_format.value;

        // do your update settings stuffs
    }
});

كما يمكنك أن ترى في مخرجات العزلة ، أيًا كان اختيارك لخيارات مربعات التحديد ، تكون القيمة المخصصة الخاصة بك ، أو القيمة 0 ، 1 ، 2 التي تم إنشاؤها تلقائيًا بواسطة AngularJS ، لا يهم في مخرجاتك إلا إذا كنت تستخدم jQuery أو أي مكتبة أخرى للوصول إلى قيمة تحديد خيارات مربع التحرير والسرد هذه ومعالجتها وفقًا لذلك.




كان هذا أفضل ملاءمة لكل السيناريوهات وفقًا لي:

<select ng-model="mySelection.value">
   <option ng-repeat="r in myList" value="{{r.Id}}" ng-selected="mySelection.value == r.Id">{{r.Name}}
   </option>
</select>

حيث يمكنك استخدام نموذجك لربط البيانات. ستحصل على القيمة كما سيحتوي الكائن والاختيار الافتراضي على أساس السيناريو الخاص بك.




بالنسبة للكائن:

<select ng-model="mySelect" ng-options="key as value for (key, value) in object"></select>



إذا كنت ترغب في تغيير قيمة عناصر خيارك لأن النموذج سيتم إرساله في النهاية إلى الخادم ، بدلاً من القيام بذلك ،

<select name="text" ng-model="text" ng-options="select p.text for p in resultOptions"></select>

انت تستطيع فعل ذالك:

<select ng-model="text" ng-options="select p.text for p in resultOptions"></select>
<input type="hidden" name="text" value="{{ text }}" />

ثم سيتم إرسال القيمة المتوقعة من خلال النموذج تحت الاسم الصحيح.




إليك كيفية حل هذه المشكلة في تطبيق قديم:

في HTML:

ng-options="kitType.name for kitType in vm.kitTypes track by kitType.id" ng-model="vm.itemTypeId"

في JavaScript:

vm.kitTypes = [
    {"id": "1", "name": "Virtual"},
    {"id": "2", "name": "Physical"},
    {"id": "3", "name": "Hybrid"}
];

...

vm.itemTypeId = vm.kitTypes.filter(function(value, index, array){
    return value.id === (vm.itemTypeId || 1);
})[0];

My HTML displays the option value properly.




يمكنك استخدام خيارات ng لتحقيق ربط علامة محدد لقيمة وعرض الأعضاء

أثناء استخدام مصدر البيانات هذا

countries : [
              {
                 "key": 1,
                 "name": "UAE"
             },
              {
                  "key": 2,
                  "name": "India"
              },
              {
                  "key": 3,
                  "name": "OMAN"
              }
         ]

يمكنك استخدام الرابط أدناه لربط علامة التحديد بالقيمة والاسم

<select name="text" ng-model="name" ng-options="c.key as c.name for c in countries"></select>

إنها تعمل بشكل رائع




لا يقوم توجيه ng-options بتعيين سمة القيمة على عناصر <options> للصفائف:

استخدام limit.value as limit.text for limit in limits يعني:

قم بتعيين علامة <option> أنها limit.text
احفظ القيمة limit.value في select ng-model

راجع question لا تمثل AngularJS ng-options القيم .




Related