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

时间:2013-09-19 02:05:59

标签: javascript jquery ajax angularjs

我有这个控制器:

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;
    }
});

我的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>

更新:请注意,它适用于<input>旁边的<select>,但不适用于<header>(仅绑定一次)

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

我尝试过不使用

$scope.selectedUser = data[0];

但仍然无法正常工作,虽然我指定ng-model="selectedUser"但它完全没有约束。

JSON返回:

[
    {
        "id": 1,
        "role_id": 1,
        "created_at": "2013-09-19 05:54:36",
        "updated_at": "2013-09-19 05:54:36",
        "email": "admin@admin.com",
        "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": "johndoe@gmail.com",
        "username": "john",
        "first_name": "John",
        "last_name": "Doe"
    }
]

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

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

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

用来解释我的问题:http://jsfiddle.net/jofrysutanto/4nfyV/3/

2 个答案:

答案 0 :(得分:5)

试试这个

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>    

控制器:

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": "admin@admin.com",
     "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": "johndoe@gmail.com",
     "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;
}
});

请参阅DEMO

答案 1 :(得分:0)

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

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

或者将其更改为使用ID或类似的内容。

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