Angular 更改单个值会在全局范围内更改值

Angular altering individual value changes value globally

我不太确定这个问题的名称,但这是我的问题:

我有以下数组:

    $scope.competenceArray =[];

此数组包含以下对象:

var competence = {competence_type_id: type_id, id: id ,name: "name", organization_id: organization_id};

它包含大约 50 种此对象。

然后我有另一个数组:

    $scope.jobprofiles = [];

此数组包含以下多个对象:

    $scope.jobprofile = {name: name, selectedCompetence: [competence]};

所以每个 jobprofile 都有一个 name 值和一个 competence

的数组

到目前为止一切顺利。

然后我有以下select:

<div class="form-group">
<label>Vælg kompetencer</label>
<ui-select multiple ng-model="jobprofile.selectedCompetence" theme="bootstrap"
           ng-disabled="disabled">
    <ui-select-match placeholder="Vælg kompetencer">{{$item.name}} &lt;{{$item.competence_type_id ==
        1 ? 'Faglig' : 'Personlig' }}&gt;</ui-select-match>
    <ui-select-choices group-by="someGroupFn"
                       repeat="competence in competenceArray | propsFilter: {name: $select.search, competence_type_id: $select.search}">
        <div ng-bind-html="competence.name | highlight: $select.search"></div>
        <small>
            {{competence.competence_type_id == 1 ? 'Faglig' : 'Personlig'}}
        </small>
    </ui-select-choices>
</ui-select>

基本上这允许我将多个 competence 对象添加到我的 jobprofile.selectedCompetence

完成后,我将这些添加到 editable table:

                    <table class="table table-bordered table-hover table-condensed bg-white-only">
                    <tr style="font-weight: bold">
                        <td style="width:35%">Navn</td>
                        <td style="width:20%">Forventet niveau</td>
                        <td style="width:25%">Ret</td>
                    </tr>
                    <tr ng-repeat="selectCompetence in row.selectedCompetence">
                        <td class="v-middle">
                            <!-- editable username (text with validation) -->
<span editable-select="selectCompetence.name" e-name="name" e-ng-options="s.name as s.name for s in competenceArray" e-form="rowform" onbeforesave="checkName($data, user.id)"
      e-required>
  {{ selectCompetence.name || 'empty' }}
</span>
                        </td>
                        <td class="v-middle">
                            <!-- editable status (select-local) -->
<span editable-select="selectCompetence.level" e-name="level" e-form="rowform"
      e-ng-options="level.level_id as level.level_id for level in levelsArray">
  {{ selectCompetence.level  }}
</span>
                        </td>
                        <td style="white-space: nowrap">
                            <!-- form -->
                            <form editable-form name="rowform" onbeforesave="saveUser($data, user.id)"
                                  ng-show="rowform.$visible" class="form-buttons form-inline"
                                  shown="inserted == user">
                                <button type="submit" ng-disabled="rowform.$waiting"
                                        class="btn btn-sm btn-info">
                                    save
                                </button>
                                <button type="button" ng-disabled="rowform.$waiting"
                                        ng-click="rowform.$cancel()" class="btn btn-sm btn-default">
                                    cancel
                                </button>
                            </form>
                            <div class="buttons" ng-show="!rowform.$visible">
                                <button class="btn btn-sm btn-info" ng-click="rowform.$show()"><i class="fa fa-edit"></i></button>
                                <button class="btn btn-sm btn-danger" ng-click="removeCompetence(row,$index)"><i class="fa fa-times"></i></button>
                            </div>
                        </td>
                    </tr>
                </table>

首先我遍历 jobprofiles 数组

中的所有 jobprofile

然后对于每个 jobprofile 我循环遍历他们的数组 competence

<tr ng-repeat="selectCompetence in row.selectedCompetence">

这工作正常并且没有问题但是随后发生了一些奇怪的事情:

你需要注意的是下面这行代码:

<td class="v-middle">
    <span editable-select="selectCompetence.level" e-name="level" e-form="rowform"
          e-ng-options="level.level_id as level.level_id for level in levelsArray">
      {{ selectCompetence.level  }}
    </span>

在这里,我可以使用以下数组编辑每个 selectedCompetencelevel

    $scope.levelsArray = [
        {level_id: 1},
        {level_id: 2},
        {level_id: 3},
        {level_id: 4},
        {level_id: 5},
        {level_id: 6},
        {level_id: 7},
        {level_id: 9},
        {level_id: 9},
        {level_id: 10}
    ];

现在进入实际问题。

当我将值 level 添加到 selectedCompetence 时,它会自动将值添加到 competenceArray 中的对象。我调试了一下,发现可能是因为它们的hash值相同。但是谁能告诉我如何避免这种情况?

javascript 中的对象通过引用传递。因此,当您向作业添加权限时,您实际上已经获得了对权限数组中同一对象的引用。

我的方法是:

  1. 使用angular.copy将整个对象复制到作业自己的能力数组中,然后编辑它们。

  2. 创建一个对象,其键与能力 ID 对应,值与能力级别 ID 对应。

据我所知,您正在通过引用传递对象,因此您实际上是在处理同一个对象,为避免这种情况,您需要在通过任一方式传递时创建一个副本

angular.copy(obj)

Object.create(obj)