javascript 来自 AJAX 调用的 <option> AngularJS <select> 双向数据绑定

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18885177/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 13:33:23  来源:igfitidea点击:

AngularJS <select> two way data binding for <option> coming from AJAX call

javascriptjqueryajaxangularjs

提问by JofryHS

I have this Controller:

我有这个控制器:

JApp.controller('WebsiteController', function($scope, $resource) {
    var UsersService = $resource('/auth/users', {});

    $scope.adding = false;
    $scope.users = [];

    $scope.addUser = function() {
        $scope.adding = true;

        UsersService.query({}, function(data) {
            $scope.users = data;
            $scope.selectedUser = data[0];
        });
    }

    $scope.cancelAddUser = function() {
        $scope.adding = false;
    }
});

My HTML:

我的 HTML:

<section class="vbox" ng-controller="WebsiteController">
<section class="panel animated fadeInDown">
    <header class="panel-heading">
      <h3>{{selectedUser.last_name}} </h3> <!-- Just to test I print it here -->
    </header>
    <div class="panel-body m-b">
        <div class="row text-sm wrapper">
            @if (role_admin())
                <a href="{{{URL::action('WebsiteController@getAddWebsite')}}}" class="btn btn-sm btn-info"> <i class="icon-plus"></i> New Website </a>
            @endif                  

        </div>
        <div class="table-responsive">
            <table class="table table-striped b-t text-sm">
              <thead>
                  <tr>
                    <th>URL</th>
                    <th>Assigned to</th>
                    <th>Action</th>
                  </tr>
                </thead>
                <tbody>
                                    <!-- Outside this <tr> doesn't work -->
                    <tr ng-repeat="website in websites">
                        <td> {{website.url}}</td>
                        <td>
                             <span ng-repeat="assigned in website.users"> <span class="label label-info"> {{assigned.first_name}} </span> &nbsp; </span>
                             <a ng-click="addUser()" ng-hide="adding" class="btn btn-success btn-xs"> Add new </a></span>                               
                                 <select ng-hide="!adding" 
                                            name="myselect" 
                                            ng-model="selectedUser" 
                                            ng-options="u.first_name for u in users">
                                 </select>
                             <a href="#" ng-hide="!adding" ng-click="cancelAddUser()" class="btn btn-warning btn-xs">Cancel</a>
                             <input type="text" ng-model="selectedUser.first_name"> <!-- It works here! -->
                        </td>
                        <td>
                            <a href="#" class="btn btn-xs btn-white"> <i class="icon-pencil"></i> Edit </a>
                        </td>
                    </tr>
                </tbody>                    
            </table>
        </div>
    </div>
</section>
</section>

Updated: Notice that it works in my <input>next to the <select>, but doesn't work in my <header>(only binds once)

更新:请注意,它在 my<input>旁边<select>工作,但在 my 中不起作用<header>(仅绑定一次)

So when I click on the add user, the AJAX call will retrieve list of users, and successfully show it in the <select>and by default, selectedUserwill be pointing at data[0]which is the first user. But now the two way binding is now bound to data[0]instead. If I change my selection to other user, selectedUseris not updated. But if I update my selectedUser, let's say the name, the name in the dropdown list also change.

因此,当我单击添加用户时,AJAX 调用将检索用户列表,并成功显示在<select>默认情况下,selectedUser将指向data[0]第一个用户。但是现在双向绑定现在绑定到了data[0]。如果我将我的选择更改为其他用户,selectedUser则不会更新。但是,如果我更新我的selectedUser,假设名称,下拉列表中的名称也会更改。

I have tried not using the line

我试过不使用线路

$scope.selectedUser = data[0];

but still doesn't work anyway, it is not bound at all though I specify ng-model="selectedUser".

但无论如何仍然不起作用,尽管我指定了它根本不受约束ng-model="selectedUser"

The JSON returned:

JSON 返回:

[
    {
        "id": 1,
        "role_id": 1,
        "created_at": "2013-09-19 05:54:36",
        "updated_at": "2013-09-19 05:54:36",
        "email": "[email protected]",
        "username": "admin",
        "first_name": "Admin",
        "last_name": "Istrator"
    },
    {
        "id": 2,
        "role_id": 2,
        "created_at": "2013-09-19 05:54:36",
        "updated_at": "2013-09-19 05:54:36",
        "email": "[email protected]",
        "username": "john",
        "first_name": "John",
        "last_name": "Doe"
    }
]

Anyone can help me with this? I am trying not to go down the $digest or $apply road if I don't have to.

任何人都可以帮助我吗?如果我不需要,我会尽量不走 $digest 或 $apply 这条路。

UPDATE 2The source of the problem is if I try to print out selectedUser outside of the following ng-repeat in my above HTML:

更新 2问题的根源在于,如果我尝试在上述 HTML 中的以下 ng-repeat 之外打印 selectedUser:

<tr ng-repeat="website in websites"> ...... </tr>

Fiddle to illustrate my problem: http://jsfiddle.net/jofrysutanto/4nfyV/3/

小提琴来说明我的问题:http: //jsfiddle.net/jofrysutanto/4nfyV/3/

回答by Nitish Kumar

Try This

试试这个

HTML:

HTML:

   <div ng-app="myApp">
    <section class="vbox" ng-controller="WebsiteController">
   <section class="panel animated fadeInDown">
<header class="panel-heading">
  <h3>{{mySelectedUser.last_name}} </small> <!-- Just to test I print it here -->
</header>
<div class="panel-body m-b">
    <div class="table-responsive">
        <table class="table table-striped b-t text-sm">
          <thead>
              <tr>
                <th>URL</th>
                <th>Assigned to</th>
                <th>Action</th>
              </tr>
            </thead>
            <tbody>
                <tr ng-repeat="website in websites">
                    <td>
                         <span ng-repeat="assigned in website.users"> <span class="label label-info"> {{assigned.first_name}} </span> &nbsp; </span>
                         <a ng-click="addUser()" ng-hide="adding" class="btn btn-success btn-xs"> Add new </a></span>                               
                             <select ng-hide="!adding" 
                                        name="myselect" 
                                        ng-model="selectedUser" 
                                        ng-change="abc(selectedUser)"
                                        ng-options="u.first_name for u in users">
                             </select>
                         <a href="#" ng-hide="!adding" ng-click="cancelAddUser()" class="btn btn-warning btn-xs">Cancel</a>
                         <input type="text" ng-model="selectedUser.first_name"> <!-- It works here! -->
                    </td>
                    <td>
                        <a href="#" class="btn btn-xs btn-white"> <i class="icon-pencil"></i> Edit </a>
                    </td>
                </tr>
            </tbody>                    
        </table>
    </div>
</div>
 </section>
</section>
</div>    

Controller :

控制器 :

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

 JApp.controller('WebsiteController', function($scope) {
//var UsersService = $resource('/auth/users', {});

$scope.adding = false;
$scope.users = [];

$scope.websites = [
    {
        "id": 1,
        "url": "www.google.com",
        "cms": "Wordpress"
    }
    ];

$scope.addUser = function() {
    $scope.adding = true;
   var data = [
   {
     "id": 1,
     "role_id": 1,
     "created_at": "2013-09-19 05:54:36",
     "updated_at": "2013-09-19 05:54:36",
     "email": "[email protected]",
     "username": "admin",
     "first_name": "Admin",
     "last_name": "Istrator"
   },
  {
     "id": 2,
     "role_id": 2,
     "created_at": "2013-09-19 05:54:36",
     "updated_at": "2013-09-19 05:54:36",
     "email": "[email protected]",
     "username": "john",
     "first_name": "John",
     "last_name": "Doe"
  }
];
   // UsersService.query({}, function(data) {
        $scope.users = data; // suppose data is coming from UsersService.query
        $scope.selectedUser = data[1];
        $scope.mySelectedUser = $scope.selectedUser ;
  //  });
}
$scope.abc = function(a) {
    $scope.mySelectedUser = a;

 }
$scope.cancelAddUser = function() {
    $scope.adding = false;
}
});

See DEMO

演示

回答by Zack Argyle

The value of the select dropdown options is u.first_name, so either do this:

选择下拉选项的值是 u.first_name,所以要么这样做:

$scope.selectedUser = data[0].first_name;

Or change it to use ids or something like this.

或者将其更改为使用 ids 或类似的东西。

ng-options="u.id as u.first_name for u in users"
$scope.selectedUser = data[0].id;