如何使用选择列表从指令更新父模型

时间:2015-12-14 18:51:35

标签: javascript angularjs angularjs-directive

我有一个创建选择列表的指令。我需要传入对象的id和value键,因为这是一个可重用的控件。为什么列表在更新时不会绑定到其父模型?

http://plnkr.co/edit/KHALRK1fBigZ2dj3bSlT?p=preview

的index.html

  <!doctype html>
<html ng-app="app">
<head>
</head>
<body>
  <div ng-controller="Ctrl">
    <my-dir list="characters" 
            model="model.character"
            selected-item="model.character.id"
            value-key="id" 
            text-key="name">
    </my-dir>
    <button ng-click="check()">Check</button>
  </div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
  <script src="script.js"></script>
</body>
</html>

的script.js

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

app.controller('Ctrl', function($scope) {

  $scope.model = { character: { id: 2, name: 'Link' } };
  $scope.characters = [
      { id: 1, name: 'Mario' },
      { id: 2, name: 'Link' },
      { id: 3, name: 'Bowser' }
    ];

  $scope.check = function() {
    alert($scope.model.character.name);
  };
});

app.directive('myDir', function() {
  return {
    restrict: 'E',
    controller: function($scope) {
    },
    template: "<select ng-model='vm.model'>"
    + "<option value=''></option>"
    + "<option ng-repeat='item in vm.list' ng-selected='item[vm.valueKey]===vm.selectedItem' "
    + "value='item[vm.valueKey]' ng-bind='item[vm.textKey]'>"
    + "</option>"
    + "</select>",
    controllerAs: 'vm',
    bindToController: true,
    scope: {
      model:'=',
      list:'=',
      valueKey:'@',
      textKey:'@',
      selectedItem:'='
    }
  };
});

修改

这有效,但是除非有人可以提出建议,否则有空白选项会有点麻烦吗?

<select ng-model="vm.model" ng-options="item as item[vm.textKey] for item in vm.list track by item[vm.valueKey]"></select>

编辑2:

有没有办法添加到视图中,以便空白选项实际绑定到模型并使其属性为null,而不是使实际模型等于null?

因此,对于给定的示例,空白值实际上应该如下所示:

$scope.model = { character: { id: null, name: null } };

而不喜欢

$scope.model = { character: null };

当我们从列表中选择该空白值时会发生什么。由于这是一个可重用的控件,因此在此处添加它将更加简洁,而不是修改每个对象数组的所有源数据以添加该空值。

我使用以下方法解决了这个问题:

<select ng-model="vm.model" ng-change="selectChange()" ng-options="item as item[vm.textKey] for item in vm.list track by item[vm.valueKey]">
    <option value=""></option>
</select>

...

    $scope.selectChange = function () {
        if ($scope.vm.model === null) {
            var blankItem = {};
            blankItem[$scope.vm.valueKey] = null;
            blankItem[$scope.vm.textKey] = null;
            $scope.vm.model = blankItem;
        }
    };

1 个答案:

答案 0 :(得分:0)

Daniel_Lmasa提供的答案建议使用select的angular指令,然后添加内容以在选择列表的开头转置空白值:

<select ng-model="vm.model" ng-options="item as item[vm.textKey] for item in vm.list track by item[vm.valueKey]">
    <option value=""></option>
</select>

将正确创建绑定到模型的所有字符,并且还会添加一个空白选项,该选项将在保存模型时发布为空。

如果我们愿意:

$scope.model = { character: { id: null, name: null } };

而不是

$scope.model = { character: null };

要在select上绑定我们的模型,那么我们可以这样做:

<select ng-model="vm.model" ng-change="selectChange()" ng-options="item as item[vm.textKey] for item in vm.list track by item[vm.valueKey]">
    <option value=""></option>
</select>

...

    $scope.selectChange = function () {
        if ($scope.vm.model === null) {
            var blankItem = {};
            blankItem[$scope.vm.valueKey] = null;
            blankItem[$scope.vm.textKey] = null;
            $scope.vm.model = blankItem;
        }
    };