AngularJS:模型切换到字符串的int

问题描述 投票:10回答:3

我目前正在开发Angular中的应用程序。到目前为止,一切都很顺利。对于棱角分明,我真的非常非常新,我很惊讶第一个真正的障碍花了这么长时间。

情况:

我有一个对象数组,每个对象都有一个订单。

category.items = [{id: 1, order: 1, type: {}, ...}, {id: 54, order: 2, type: {}, ...}, {id: 3, order: 3, type: {}, ...}]

用户需要能够重新排列这些项目。必须将新订单设置为对象属性“订单”。

在html中,这些对象的呈现方式如下:

<div class="category">
    <div class="item" ng-repeat="(itemIndex, item) in category.items track by $index">
        <div class="header">
        </div>
    </div>
</div>

在header-div中我有一个输入字段,类型为select。

<select ng-model="item.order"  ng-change="changeItemOrder((itemIndex + 1), item.order, itemIndex)">
  <option ng-repeat="item in category.items" ng-value="($index + 1)">{{$index + 1}}</option>
</select>

changeItemOrder的代码:

$scope.changeItemOrder = function(old_order, new_order, item_index) {
    new_order = parseInt(new_order);
    if (old_order != new_order) {
        var upper = Math.max(old_order, new_order);
        var lower = Math.min(old_order, new_order);

        angular.forEach($scope.category.items, function(item, key) {
            if (item_index != key) {
                if (new_order < old_order) {
                    if (item_index >= new_order && (key + 1) >= lower && (key + 1) <= upper) {
                        item.order = (parseInt(item.order) + 1);
                    }
                } else if (new_order > old_order) {
                    if (item_index <= old_order && (key + 1) <= upper && (key + 1) >= lower) {
                        item.order = (parseInt(item.order) - 1);
                    }
                }
            } else {
                item.order = parseInt(new_order);
            }
        });

        $scope.reorderItems();
    }
};

(ReorderItems只使用默认排序机制调用角度排序,比较顺序并返回-1,1或0)

这是我在这个问题的可能解决方案之一中发现/发现/查明其中一个突破性错误的地方。在这里,我注意到我的INT以某种方式转换为字符串,因为在渲染时,选项被添加到值为'string:2'的下拉列表中。

我已经以各种可能的方式尝试过ng-options,但即便是那些也导致了问题。我做ng-options的方式是将item.order作为item.order在...等等,只是让订单切换到某种程度上所有项目都有相同的顺序。尝试不同的分组方法或trackbys只会给出不同的错误,例如在下拉列表中突然引入NaN en NULL,或者从item-object中完全删除order属性。

到目前为止,最少有错误的解决方案一直在我的选项上使用ng-repeat。这只会导致item.order类型不匹配。

现在,经过广泛的搜索,花费数小时的stackoverflow(特别是在用那个漂亮的小问题搜索东西写这个问题之前)我来找你。

  1. 如何停止/规避我的item.order从INT切换到STRING的行为?
  2. 如果那是不可能的,我怎么能强制我的$ index成为一个字符串,所以模型(字符串)匹配值(字符串)
  3. 如果那是不可能的,我怎么能写我的ng-options让我得到我想要的行为? (我已经认真尝试了很多,从跟踪到不同的语句和语句,都导致了不同的错误) 在初始加载时,所有选择都显示选择了正确的值,因此所有item.order最初都是INT(我从我们的API获取它们),只有在交互之后,除触发重新排序的对象之外的所有内容都会搞砸之后。
javascript angularjs ng-options angular-ngmodel angularjs-ng-options
3个回答
5
投票

它被更改为字符串,因为HTML没有整数是什么的概念。最终,从DOM读取所选变量并将其传递给角度,因此它会改变其类型。

您可以强制模型始终包含带指令的整数

directive('forceInt', function() {
  return {
    require: 'ngModel',
    link: function(scope, element, attrs, controller) {     
      controller.$parsers.push(function(value) {
        if (typeof value === 'string') {
          value = parseInt(value, 10);  
          controller.$setViewValue(value);
          controller.$render();
        }
        return value;
      });
    }
  };
});

(Qazxswpoi)

但是我看到有人已经指出可能有更好的方法来跟踪排序。 FWIW该指令至少会确保模型永远不是一个字符串。


4
投票

最终我通过这样做来解决这个问题:

plunk

这个,只有这个解决方案(到目前为止)有我想要/需要的东西。我需要item.order模型来跟踪当前位置并在初始加载时显示正确的值。你不能将模型设置为questionIndex,因为这扰乱了其他HTML元素,我无法将其设置为$ index,因为这也做了奇怪的事情。

虽然其他解决方案在这里建议“工作”,但它们不会产生给我的规范。所以我想这有点具体。


0
投票
<div class='header'>
    <select ng-model="item.order" ng-change="changeItemOrder((itemIndex + 1), item.order, itemIndex)">
        <option ng-repeat="thing in category.items" ng-selected="(item.order === ($index + 1))" value="{{$index + 1}}">{{$index + 1}}</option>
    </select>
</div>
© www.soinside.com 2019 - 2024. All rights reserved.