AngularJS:当ng-model是一个数组时,未选择SELECT选项

时间:2017-03-28 21:03:46

标签: javascript html angularjs arrays

如何在不使用从array更改的情况下,破碎示例(如下)工作(因为我有很多代码依赖于它在应用程序的其他部分是array吗?

我想继续使用array,但我想要正确的选择选项来显示模型何时更改。单击按钮时模型会正确更改,但选择中未找到该选项(ng-modelng-options只是在array时才匹配)。

angular.module('app', [])
  .controller('MainCtrl', ['$scope', function($scope) {
  
    $scope.valueWorking = 'value1';
    $scope.selectFilterWorking = [{name: 'name1', value: 'value1'},{name: 'name2', value: 'value2'}];
    
    $scope.valueBroken = ['value1'];
    $scope.selectFilterBroken = [{name: 'name1', value: ['value1']},{name: 'name2', value: ['value2', 'value3']}];
    
  }]);
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<div ng-app="app" ng-controller="MainCtrl">

  <strong>Working</strong> (SELECT <i>is</i> updated when ng-model is a string):<br>
  <select ng-model="valueWorking" 
          ng-options="select.value as select.name for select in selectFilterWorking">
    <option value="">Select an Option</option>
  </select>
  <button ng-click="valueWorking='value2'">Assign to String of 'value2'</button> {{valueWorking}}<br><br>
  
  <strong>Broken</strong> (SELECT <i>not</i> updated when ng-model is an array):<br>
  <select ng-model="valueBroken" 
          ng-options="select.value as select.name for select in selectFilterBroken">
    <option value="">Select an Option</option>
  </select>
  <button ng-click="valueBroken=['value2','value3']">Assign to Array of ["value2","value3"]</button> {{valueBroken}}
  
</div>

点击上面的“运行代码段”后,请注意未选择初始选项(在已破坏选择,当它为array时),但最初是在<< strong>工作选择何时为string。单击“赋值给[数值2”]的数组时,也不会显示正确的选项。

更新:我正在尝试让OPTIONS($scope.selectFilterBroken)与MODEL匹配,而不是相反 - 因此我需要将模型保持为array。按钮单击仅用于模拟操作array的应用程序的其他部分。

任何帮助都会很棒。谢谢,请。

2 个答案:

答案 0 :(得分:3)

Javascript中的对象不相等,即使它们看起来相同但是字符串或其他原始类型。例如,var a = [1]; var b = [1]; a === b返回false。但是,如果你执行JSON.stringify(a)=== JSON.stringify(b),它将返回true。

当您将[&#39; value2&#39;]指定给valueBroken时,valueBroken将重新声明为新数组,因此它与selectFilterBroken中的数组不匹配。

要解决这个问题,我们想找到一种方法将[&#39; value2&#39;]的引用分配给valueBroken。我写了一个函数,通过比较它们的字符串化版本来查找selectFilterBroken中哪个数组与我们想要的数组匹配。找到后,将selectFilterBroken中的一个引用分配给valueBroken。

在不知道您的应用程序究竟发生了什么的情况下,很难猜测该解决方案是否适合您,但您可以从那里开始。

&#13;
&#13;
angular.module('app', [])
  .controller('MainCtrl', ['$scope', function($scope) {
  
    $scope.valueWorking = 'value1';
    $scope.selectFilterWorking = [{name: 'name1', value: 'value1'},{name: 'name2', value: 'value2'}];
    
    $scope.valueBroken = ['value1'];
    $scope.selectFilterBroken = [{name: 'name1', value: ['value1']},{name: 'name2', value: ['value2']}];

    $scope.selectBroken = function(valueAry){
    for(var i = 0, m = $scope.selectFilterBroken.length; i < m; i++){
       if(JSON.stringify($scope.selectFilterBroken[i].value) === JSON.stringify(valueAry)){

       $scope.valueBroken = $scope.selectFilterBroken[i].value;
       break;
    }
    }
    
    }
  }]);
&#13;
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<div ng-app="app" ng-controller="MainCtrl">

  <strong>Working</strong> (SELECT <i>is</i> updated when ng-model is a string):<br>
  <select ng-model="valueWorking" 
          ng-options="select.value as select.name for select in selectFilterWorking">
    <option value="">Select an Option</option>
  </select>
  <button ng-click="valueWorking='value2'">Assign to String of 'value2'</button> {{valueWorking}}<br><br>
  
  <strong>Broken</strong> (SELECT <i>not</i> updated when ng-model is an array):<br>
  <select ng-model="valueBroken" 
          ng-options="select.value as select.name for select in selectFilterBroken">
    <option value="">Select an Option</option>
  </select>
  <button ng-click="selectBroken(['value2'])">Assign to Array of ["value2"]</button> {{valueBroken}}
  
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:2)

它不绑定的原因是因为$ scope.valueBroken上的数组值与$ scope.selectFilterBroken中的数组不同。要使它们匹配,它们必须在同一个数组中。例如,我编辑了您的代码,并将$ scope.selectFilterBroken中项目的值分配给$ scope.valueBroken。现在工作正常。

&#13;
&#13;
angular.module('app', [])
  .controller('MainCtrl', ['$scope', function($scope) {
  
    $scope.valueWorking = 'value1';
    $scope.selectFilterWorking = [{name: 'name1', value: 'value1'},{name: 'name2', value: 'value2'}];
    
    
    $scope.selectFilterBroken = [{name: 'name1', value: ['value1']},{name: 'name2', value: ['value2']}];
    $scope.valueBroken = $scope.selectFilterBroken[0].value;
    
  }]);
&#13;
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<div ng-app="app" ng-controller="MainCtrl">

  <strong>Working</strong> (SELECT <i>is</i> updated when ng-model is a string):<br>
  <select ng-model="valueWorking" 
          ng-options="select.value as select.name for select in selectFilterWorking">
    <option value="">Select an Option</option>
  </select>
  <button ng-click="valueWorking='value2'">Assign to String of 'value2'</button> {{valueWorking}}<br><br>
  
  <strong>Broken</strong> (SELECT <i>not</i> updated when ng-model is an array):<br>
  <select ng-model="valueBroken" 
          ng-options="select.value as select.name for select in selectFilterBroken">
    <option value="">Select an Option</option>
  </select>
  <button ng-click="valueBroken=['value2']">Assign to Array of ["value2"]</button> {{valueBroken}}
  
</div>
&#13;
&#13;
&#13;