web-dev-qa-db-fra.com

AngularJS checkbox expression dynamique ng-true-value

J'essaie de construire une calculatrice pour les prix des garderies à Angular.

Chaque emplacement dans la franchise d'entreprise a des prix différents pour chaque jour. Donc, ma pensée était de construire un formulaire, avec d'abord une sélection qui vous permet de sélectionner l'emplacement, puis une série de cases à cocher pour les jours.

J'ai des problèmes avec ng-true-value dans les cases à cocher pour sélectionner les prix corrects dans mon fichier json.

MISE À JOUR: Plunkr ajouté: http://plnkr.co/edit/MDmrqaH1VzLBzjd5eHgT?p=preview

Considérez ce code:

        <p class="kind_section">Choose location</p>
        <select ng-model="formData.location" ng-options="location.title for location in data.bso"></select>

        <p class="kind_section">Select days</p>

        <input type="checkbox" ng-model="location.day.mon" ng-change="calculatePrice()" ng-true-value="{{data.bso[formData.location.ID].prices.monday}}" ng-false-value="0">Ma
        <input type="checkbox" ng-model="location.day.tue" ng-change="calculatePrice()" ng-true-value="{{data.bso[formData.location.ID].prices.tuesday}}" ng-false-value="0">Di<br />
        <input type="checkbox" ng-model="location.day.wed" ng-change="calculatePrice()" ng-true-value="{{data.bso[formData.location.ID].prices.wednesday}}" ng-false-value="0">Wo
        <input type="checkbox" ng-model="location.day.thu" ng-change="calculatePrice()" ng-true-value="{{data.bso[formData.location.ID].prices.thursday}}" ng-false-value="0">Do<br />
        <input type="checkbox" ng-model="location.day.fri" ng-change="calculatePrice()" ng-true-value="{{data.bso[formData.location.ID].prices.friday}}" ng-false-value="0">Vr

Tout d'abord, les ensembles de sélection formData avec un ID d'emplacement, puis je veux utiliser cet ID pour sélectionner les prix du jour pour l'emplacement correspondant et les définir sur ng-true-value.

J'utilise ng-true-value="{{data.bso[formData.location.ID].prices.monday}}" pour ça. Ça ne marche pas.

Lorsque j'ai défini l'ID manuellement comme ng-true-value="{{data.bso[0].prices.monday}}" ça marche. Pourquoi le résultat de la sélection n'est-il pas récupéré par ng-true-value?

Voici mon fichier json:

  $scope.data = {
                "bso": [
                  {
                    "ID": 0,
                    "title": "Locatie 1",
                    "prices": {
                        "monday": 130,
                        "tuesday": 130,
                        "wednesday": 200,
                        "thursday":130,
                        "friday": 130
                    }
                  },
                  {
                    "ID": 1,
                    "title": "Locatie 2",
                    "prices": {
                        "monday": 430,
                        "tuesday": 530,
                        "wednesday": 600,
                        "thursday":990,
                        "friday": 730
                    }
                  }
                ]
              };
18
Squrler

Il semble ng-true-value n'accepte pas les expressions non constantes. Depuis docs (v1.3.0) :

Certains attributs utilisés conjointement avec ngModel (tels que ngTrueValue ou ngFalseValue) n'acceptent que des expressions constantes.

Exemples d'expressions constantes:

<input type="checkbox" ng-model="..." ng-true-value="'truthyValue'">
<input type="checkbox" ng-model="..." ng-false-value="0">

Exemples d'expressions non constantes:

<input type="checkbox" ng-model="..." ng-true-value="someValue">
<input type="checkbox" ng-model="..." ng-false-value="{foo: someScopeValue}">

Une solution de contournement idéale consisterait probablement à appeler une méthode Controller sur ng-click ou ng-change à l'intérieur duquel vous pouvez analyser toutes les cases à cocher pour les valeurs véridiques ou non véridiques.

17
AlwaysALearner

L'expression dans la valeur ng-true ne sera évaluée qu'une seule fois, elle ne sera donc pas dynamique.

Une autre approche consiste à calculer les valeurs dans le rappel ng-change à la place.

Veuillez voir ma fourchette http://plnkr.co/edit/9zYS3OZ0sSkXX9rHwcgv?p=preview pour l'exemple complet.

En html:

<input type="checkbox" ng-model="selectedDays.monday" ng-change="calculatePrice()" /> Mon
<input type="checkbox" ng-model="selectedDays.tuesday" ng-change="calculatePrice()" /> Tue            <br />
<input type="checkbox" ng-model="selectedDays.wednesday" ng-change="calculatePrice()" /> Wed
<input type="checkbox" ng-model="selectedDays.thursday" ng-change="calculatePrice()" /> Thu            <br />
<input type="checkbox" ng-model="selectedDays.friday" ng-change="calculatePrice()" /> Fri

et dans le contrôleur:

$scope.calculatePrice = function(){
  $scope.formData.location.day = {};

  angular.forEach($scope.selectedDays, function (selected, day) {
    if (selected) {
      $scope.formData.location.day[day.slice(0, 3)] = $scope.data.bso[$scope.formData.location.ID].prices[day];
    }
  });
}

$scope.selectedDays = {};
2
runTarm

Une autre approche consiste à retarder la création de la case à cocher jusqu'à ce que la valeur soit prête (sur la portée ou autre).

Dans mon cas, je chargeais une valeur via http qui n'était pas sur la portée lorsque la case à cocher a été créée. Alors je l'ai juste enveloppé dans un ng-if.

          <div class="checkbox" ng-if="viewData.conditionId != undefined">
            <label>
              <input type="checkbox" ng-true-value="{{'\''+ viewData.conditionId + '\''}}" ng-false-value="undefined" ng-model="model.conditionId" required />
              I agree
            </label>
          </div>

Ce qui a parfaitement fonctionné pour mon scénario. Le vôtre est un peu différent mais le même principe devrait s'appliquer - retardez la création de la case à cocher jusqu'à ce que vous sachez la valeur à lier soit là.

Et oui, les guillemets stupides semblent nécessaires.

2
Sam