Angular Preselect / Initial Binding to Multi-Select

时间:2014-01-22 15:59:13

标签: javascript angularjs

我正在尝试绑定来自Web服务的数据,然后使用该数据预填充表单。除单个多选元素外,所有表单控件都正确绑定。如果我手动选择一个选项,模型会更新。以下是我的控制器:

myApp.controller('AdminVideosEditCtrl', [
    '$scope',
    '$http',
    '$routeParams',
    '$location',
    function($scope, $http, $routeParams, $location) {
        $http.get('/videos/' + $routeParams.videoId + '?embed=presenters').success(function(data) {
            $scope.video = data.data
            // Load providers
            $http.get('/providers').success(function(data) {
                $scope.providers = data.data;
                // Load Presenters
                $http.get('/presenters').success(function(data) {
                    $scope.presenters = data.data;
                });
            });
        });
    }
]);

最终请求返回后,我的模型看起来像这样(通过{{ video | json }}输出):

{   
    "id": "ca3ca05a-834e-47b1-aaa1-3dbe38338ca9",   
    "title": "Doloremque iure consequatur quam ea.",   
    "is_public": false,   
    "is_visible": true,   
    "url": "http://someurl.com/",   
    "provider_id": "1b4d18eb-d56c-41ae-9431-4c058a32d651",   
    "level_id": "38ed7286-da05-44b9-bfb9-e1278088d229",   
    "duration": "17:38",   
    "transcript_file": "rerum-sint-voluptatum.md",   
    "presenters": [
        {
            "id": "5111531d-5f2a-45f5-a0c4-4fa3027ff249",
            "first_name": "First",
            "last_name": "Last",
            "full_name": "First Last"
        }   
    ],   
    "provider": {
        "id": "1b4d18eb-d56c-41ae-9431-4c058a32d651",
        "title": "You Tube"   
    } 
}

以下是我在视图中多选的内容:

<div class="form-group">
    <label for="presenters" class="col-lg-2 control-label">Presenters</label>
    <div class="col-lg-10">
        <select multiple="multiple" class="form-control" id="presenters" ng-model="video.presenters" ng-options="presenter.full_name for ( id , presenter ) in presenters">
        </select>
    </div>
</div>

select元素填充正确,我希望它默认选择“First Last”元素,但不选择任何内容。我知道我的模型是正确初始化的,因为如果我手动选择元素,模型中的任何内容都不会更改(如果我选择了不同的元素,但仍保留与初始页面加载时相同的结构)。

我尝试添加$scope.$apply来电,我也试过了$scope.$root.$eval(),这两种情况都不起作用。

更新

演示者模型(包含所有演示者)在从服务中获取之后看起来像这样(名称已被更改以保护无辜者):

[
  {
    "id": "47b6e945-2d4b-44c2-b44b-adb96460864d",
    "first_name": "First",
    "last_name": "Last",
    "full_name": "First Last"
  },
  {
    "id": "5111531d-5f2a-45f5-a0c4-4fa3027ff249",
    "first_name": "One",
    "last_name": "Two",
    "full_name": "One Two"
  },
  {
    "id": "7cb1e44b-2806-4576-80b2-ae730ad356f7",
    "first_name": "Three",
    "last_name": "Four",
    "full_name": "Three Four"
  }
]

1 个答案:

答案 0 :(得分:2)

解决方案

将它放在控制器的底部

$scope.video.presenters.forEach(function(obj, idx){
    $scope.presenters.forEach(function(presenter, jdx){
        if (obj.id === presenter.id) {
            $scope.video.presenters = [$scope.presenters[jdx]]
        }
    });
});

<强> JSFIDDLE

更强大的解决方案

这更加强大,因为您可能希望预先选择多个选项。此解决方案将每个选定的选项推送到一个数组中,然后将其分配给$scope.video.presenters模型

    var selectedOptions = [];

    $scope.video.presenters.forEach(function (obj, idx) {
    $scope.presenters.forEach(function (presenter, idj) {
        if (obj.id === presenter.id) {
            selectedOptions.push($scope.presenters[idj]);
            $scope.video.presenters = selectedOptions;
        }
    });

<强> JSFIDDLE

注意:理想情况下,您应该使用id键作为对象的唯一键。 此解决方案假定并且仅适用于预选一个选项。