模型更改时ng-options不更新

时间:2016-07-28 15:48:01

标签: javascript angularjs json

我有一个看起来像的JSON对象:

[
   {
    "empName": "John",
    "ID": 1
   },
   {
    "empName": "Sam",
    "ID": 2
   },
   {
    "empName": "Ben",
    "ID": 3
   }
]

在视图中,我想要一个用户选择其中一个名称的下拉列表。我正在使用ng-options来实现这一目标:

<select ng-options="item as item.empName for item in employees track by item.ID" ng-model="emp.selected">
</select>  

如果我将JSON硬编码到控制器中的变量employees中,则选择渲染。但是,如果我使用:

$.getJSON("path to JSON file",function(json){
    $scope.employees = json;
});

未填充选择。我已经尝试添加$ scope。$ apply()无济于事。有什么建议吗?

更新1

接受来自Iso的答案我仍然选择不绑定。例如,如果我的javascript是:

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

    $scope.employees = [
       {
        "empName": "John",
        "ID": 1
       },
    ];

    $http.get(" --PATH TO JSON-- ").then(function (res) {
        $scope.employees = res.data;
        console.log($scope.employees);
    });
}]);

尽管console.log返回包含所有三个名字的完整对象,但仍然只使用名字'John'填充选择。

3 个答案:

答案 0 :(得分:1)

您需要在此处拨打$scope.$evalAsync()或使用$http代替jQuery(我建议):

$http.get("path to JSON file").then(function (res) {
  $scope.employees = res.data;
});

原因是$http知道AngularJS的摘要周期,而jQuery不是。

不要使用$scope.$apply()(如果正在进行摘要周期,则可能会失败),以及$timeout(因为它会引发所有作用域的摘要周期,因此很重要)。

答案 1 :(得分:0)

将您的代码包含在$timeout

$.getJSON("path to JSON file", function (json) {
    $timeout(function () {
        $scope.employees = json;
    })
});

当摘要周期正在进行时,对$apply的调用可能会失败。

但是考虑使用$http而不是使用jQuery来提取数据。

答案 2 :(得分:0)

您应该在Angular中使用带有$q库的promises。

var getEmployees = function () {
        var deferred = $q.defer();
        $.getJSON("path to JSON file", function (json) {
            deferred.resolve(json);
        });
        return deferred.promise;
    }

    getEmployees().then(res){
        $scope.employees = res.data;
    }

修改 如果您使用$timeout并不是一个正确的解决方案,因为它不能让您控制同步性。但是,我相信,使用$http进行通话会附带内置的承诺。