【问题标题】:Lose repeated value inside ng-options在 ng-options 中丢失重复值
【发布时间】:2017-01-20 14:13:52
【问题描述】:

plunker example

我有一些汽车和可用年限:

  • [“沃尔沃”、“大众”、“奥迪”] --> [2006、2007、2008]
  • [“福特”、“本田”、“捷豹”] --> [2008、2009、2010、2011]

注意:2008 年重复。这很重要)

我默认为沃尔沃设置了 2006 年(任何年份2008 年除外)。
点击“装载汽车 1”,然后点击“装载汽车 2”。
您还可以看到 2006 年。它有效。

但是从 2006 年到 2008 年的变化。
点击“装载汽车 1”,然后点击“装载汽车 2”。
2008 年已逝去。它不起作用。

为什么?我不明白什么? SELECT 标记的值类型(数字或字符串)无关紧要


如果我删除

//I use length = 0 in ng-disabled to user can't change 'year' while timeout interval
if (main.years) main.years.length = 0;

或 $timeout 它会起作用。
我尝试使用绑定。没用。

谢谢。


我做了简单的例子。但是在我的项目中,我有很多字段和缓慢的客户端服务器。 而且如果我很快选择汽车,汽车数组中的数据选择中的选项都会丢失

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

app.controller('MainCtrl', function($timeout) {
  var main = this;

  main.selectCar = selectCar;
  main.models = ["Volvo", "VW", "Audi", "Ford", "Honda", "Jaguar"];
  //main.years = [2006, 2007, 2008, 2009, 2010, 2011];
  main.cars = [{
    year: 2006,
    model: "Volvo"
  }, {
    year: 2011,
    model: "Honda"
  }];

  selectCar(main.cars[0]);

  // bind doesn't work too
  function selectCar(car) {
    // I use length = 0 in ng-disabled to user can't change 'year' while timeout interval
    if (main.years) main.years.length = 0; //will work without this line

    main.activeCar = car;
    getDataFromServer('years');

    console.log(main.cars[0].year);
  }

  function getDataFromServer(nameForOptions) {
    // don't think about this logic
    // $q
    $timeout(function() { //will work without $timeout
      var arr;
      if (nameForOptions === 'years') {
        if (["Volvo", "VW", "Audi"].indexOf(main.activeCar.model) > -1) {
          arr = [2006, 2007, 2008];
        } else {
          arr = [2008, 2009, 2010, 2011];
        };
      }

      main[nameForOptions] = arr;
    }, 100);
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<body ng-app="plunker" ng-controller="MainCtrl as main">
  <br /><br />
  <button ng-click="main.selectCar(main.cars[0])">Load car 1</button>
  <button ng-click="main.selectCar(main.cars[1])">Load car 2</button>
  <br /><br />
  <select id="select_1" ng-model="main.activeCar.model" ng-options="model for model in main.models" ng-disabled="!main.models.length"></select>
  <select id="select_2" ng-model="main.activeCar.year" ng-options="year for year in main.years" ng-disabled="!main.years.length"></select>
  <hr />
  <p>Cars:</p>
  <ol>
    <li ng-repeat="car in main.cars">{{car.model}} - {{car.year}}</li>
  </ol>
</body>

【问题讨论】:

  • 我知道代码在您的 plunkr 中,但最好将代码直接编辑到问题中。这样,当 plunkr 消失时(它不受 SO 控制),这个问题的代码将继续帮助其他人。
  • 使用超时等待数据是一个非常糟糕的主意,最好使用一个回调函数,一旦你得到数据就调用其余的代码。这不仅可以解决问题,而且通常是一种更好的做法。
  • 阿米尔·塔利奇,谢谢。我和你想。但是如果我使用 $q 并返回 deferred.promise 这不会解决我的问题。在我的情况下也是如此。 plunker
  • 目前还不清楚您在这里要做什么;这段代码混杂在一起。首先,当您设置main.years.length = 0; 时,您正在破坏绑定。其次,不清楚为什么要尝试使用单个数组来管理两个不同的值。

标签: javascript angularjs


【解决方案1】:

请将 activeCar 初始化为空对象。 main.activeCar = {};

【讨论】:

  • 提供了更新的 plunker 链接。你能试一试吗?不知何故,它对我有用。
  • 我为沃尔沃选择 2008 年,选择汽车 2,然后选择汽车 1。看到的是 2006 年,而不是 2008 年。
  • 哦小姐理解需求,这是更新的plunker plnkr.co/edit/SroXTO0KuHE7BpCGSY4A?p=preview
【解决方案2】:

我是这样做的 plunker fork

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

app.controller('MainCtrl', function($q, $timeout) {
  var main = this;
  main.selectCar = selectCar;
  
  main.models = ["Volvo", "VW", "Audi", "Ford", "Honda", "Jaguar"];

  main.cars = [
    {
      year: 2006,
      model: "Volvo"
    },
    {
      year: 2011,
      model: "Honda"
    }
  ];
  
  selectCar(main.cars[0]);

  function selectCar(car){
    //I use length = 0 in ng-disabled to user can't change 'year' while timeout interval (wait server response)
    if (main.years) main.years.length = 0;
    
    main.activeCar = {};

    getDataFromServer('years', car).then(function(){
      main.activeCar = car;
      console.log(main.cars);
    });
  }
  
  function getDataFromServer(nameForOptions, car){
    //don't think about this function and logic inside it
    var deferred = $q.defer();

    //wait server response
    $timeout(function(){
      var arr;
      if (nameForOptions === 'years') {
        if (["Volvo", "VW", "Audi"].indexOf(car.model) > -1) {
          arr = [2006, 2007, 2008];
        } else {
          arr = [2008, 2009, 2010, 2011];
        };
      }
      
      main[nameForOptions] = arr;
      
      deferred.resolve();
    }, 100);
    
    return deferred.promise;
  }

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<body ng-app="plunker" ng-controller="MainCtrl as main">
  <br /><br />
  <button ng-click="main.selectCar(main.cars[0])">Load car 1</button>
  <button ng-click="main.selectCar(main.cars[1])">Load car 2</button>
  <br /><br />
  <select id="select_1" ng-model="main.activeCar.model" ng-options="model for model in main.models" ng-disabled="!main.models.length"></select>
  <select id="select_2" ng-model="main.activeCar.year" ng-options="year for year in main.years" ng-disabled="!main.years.length"></select>
  <hr />
  <p>Cars:</p>
  <ol>
    <li ng-repeat="car in main.cars">{{car.model}} - {{car.year}}</li>
  </ol>
</body>

【讨论】:

    猜你喜欢
    • 2018-11-02
    • 1970-01-01
    • 2015-02-21
    • 1970-01-01
    • 1970-01-01
    • 2015-03-08
    • 1970-01-01
    • 2014-03-11
    相关资源
    最近更新 更多