AngularJS下拉绑定

时间:2015-12-27 16:09:14

标签: javascript angularjs

我创建了一个正确填充的下拉列表,该下拉列表捕获所选值的更改。但是,在我的表单中,我有一个对象列表(团队),我想点击列表中的一个团队,并在下拉列表中填入该团队的正确详细信息。

编辑:我已将代码更改为使用工厂,然后我可以将其注入控制器。

以下是下拉列表:

(function () {

    "use strict";

    //getting the existing module
    angular.module("app")
        .controller("divisionsController", divisionsController)
        .directive("divisionDropdown", divisionDropdown);

    //inject http service
    function divisionsController($http, $scope, divisionService) {

        //$scope.divisions = divisionService.all();
    };

    function divisionDropdown() {
        return {
            restrict: "E",
            scope: false,
            controller: "divisionsController",
            template: "<select class='form-control' ng-model='selectedDivision' ng-options='division.divisionName for division in divisions' required>\
                                <option style='display:none' value=''>{{'Select'}}</option>\
                            </select>"
        };
    }
})();

以下是我使用它的表格:

    <div class="row" id="divTeam" ng-app="app" ng-controller="teamsController as vm">
            <div class="col-md-4">
                <div class="panel panel-info">

                    <div class="panel-body">

                        <form novalidate id="AddUpdateTeam" name="AddUpdateTeam" ng-submit="vm.addUpdateTeam()">

                            <!--addTeam or updateTeam-->
                            <div class="form-group">
                                <input type="text" ng-model="vm.newTeam.teamId"/>
                            </div>
                            <div class="form-group">
                                <label for="teamName">Team Name</label>
                                <input id="teamName" type="text" class="form-control" name="teamName" ng-model="vm.newTeam.teamName"
                                       required ng-minlength="5" ng-maxlength="50"/>
                                <span ng-show="AddUpdateTeam.teamName.$error.required" class="text-warning">Team Name is required</span>
                                <span ng-show="AddUpdateTeam.teamName.$error.minlength" class="text-warning">Team Name must be at least 5 characters</span>
                                <span ng-show="AddUpdateTeam.teamName.$error.maxlength" class="text-warning">Team Name must be no more than 50 characters</span>
                            </div>
...
                            <div class="form-group">
                                <label for="divisionName">Division Name</label>
                                <division-dropdown></division-dropdown>
                                <p>selected division is : {{ selectedDivision | json }}</p>
                            </div>
                            <div class="form-group">
                                <label for="coachName">Coach Name</label>
                                <coaches-dropdown></coaches-dropdown>
                                <p>selected coach is : {{ vm.newTeam.coach | json }}</p>
                            </div>
                            <div class="form-group">
                                <label for="logoImage">Logo Image</label>
                                <input id="logoImage" type="text" class="form-control" name="logoImage" ng-model="vm.newTeam.logoImage"
                                       required ng-minlength="20" ng-maxlength="100" />
                                <span ng-show="AddUpdateTeam.logoImage.$error.required" class="text-warning">Logo Image is required</span>
                                <span ng-show="AddUpdateTeam.logoImage.$error.minlength" class="text-warning">Logo Image must be at least 20 characters</span>
                                <span ng-show="AddUpdateTeam.logoImage.$error.maxlength" class="text-warning">Logo Image must be no more than 100 characters</span>
                            </div>
                            <div class="form-group">
                                <button type="submit" ng-disabled="AddUpdateTeam.$invalid">Save</button>
                            </div>
                        </form>
                        @*<button data-bind="click:team.clearInputFields()">Cancel</button>*@
                    </div>

                </div>
            </div>

            <div class="col-md-8">
                <div class="text-danger" ng-show="vm.errorMessage">{{ vm.errorMessage }}</div>
                <wait-cursor></wait-cursor>
                <div class="panel panel-primary">
                    <div class="panel-heading">
                        <h2 class="panel-title">Teams</h2>
                    </div>

                    <table class="table table-striped table-bordered table-condensed">
                        <thead>
                        <tr>
                            <th>ID</th>
                            <th>Name</th>
                            <th>Division</th>
                            <th>Coach</th>
                        </tr>
                        </thead>

                        <tbody ng-repeat="team in vm.teams">
                            <tr>
                                <td>{{ team.teamId }}</td>
                                <td>{{ team.teamName }}</td>
                                <td>{{ team.division.divisionName }}</td>
                                <td>{{ team.coach.coachName }}</td>
                                <td><a ng-click="vm.editTeam(team)" class="btn btn-sm btn-primary">Edit</a></td>
                                <td><a ng-click="vm.deleteTeam(team)" class="btn btn-sm btn-danger">Delete</a></td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>

这是teamsController:

    (function () {

    "use strict";

    //getting the existing module
    angular.module("app")
        .controller("teamsController", teamsController);

    //inject http service
    function teamsController($scope, $http, divisionService) {

        $scope.divisions = divisionService.all();

        var vm = this;

        vm.teams = [];

        vm.newTeam = {};

        vm.errorMessage = "";
        vm.isBusy = true;

        //matched to verb, returns promise
        $http.get('http://localhost:33201/api/Teams')
            .then(function(response) {
                //first parameter is on success
                //copy response.data to vm.teams (could alternatively use a foreach)
                angular.copy(response.data, vm.teams);
            }, function(error) {
                //second parameter is on failure
                vm.errorMessage = "Failed to load data: " + error;
            })
            .finally(function() {
                vm.isBusy = false;
            });

        vm.editTeam = function(team) {

            vm.newTeam.division = team.division;
            $scope.selectedDivision = team.division;


            vm.newTeam.teamId = team.teamId;
            vm.newTeam.teamName = team.teamName;
            vm.newTeam.cheerleaderImage = team.cheerleaderImage;
            vm.newTeam.coachImage = team.coachImage;
            vm.newTeam.headerImage = team.headerImage;
            vm.newTeam.coach = team.coach;
            vm.newTeam.logoImage = team.logoImage;
        }

        vm.addUpdateTeam = function() {

            if (vm.team === undefined) {

                //define a service, inject that service into both controllers
                vm.newTeam.division = $scope.selectedDivision;


                //map divisionid and coachid 
                vm.newTeam.divisionId = vm.newTeam.division.divisionId;
                vm.newTeam.coachId = vm.newTeam.coach.coachId;

                vm.isBusy = true;
                vm.errorMessage = "";

                //post, pass newTeam object
                $http.post('http://localhost:33201/api/Teams/Add', vm.newTeam)
                    .then(function(response) {
                        //success
                        vm.teams.push(response.data);
                        vm.teams.sort(function (a, b) {
                            if (a.teamName.toLowerCase() < b.teamName.toLowerCase()) return -1;
                            if (a.teamName.toLowerCase() > b.teamName.toLowerCase()) return 1;
                            return 0;
                        });
                        vm.newTeam = {}; //clear form
                    }, function(error) {
                        //failure
                        vm.errorMessage = "Failed to save new team: " + error;
                    })
                    .finally(function() {
                        vm.isBusy = false;
                    });
            } else {

                alert("edit" + vm.team.teamId);


            }
        }

        vm.deleteTeam = function (team) {

            //bind view model to team
            vm.newTeam.teamId = team.teamId;

            vm.isBusy = true;
            vm.errorMessage = "";

            //delete, pass newTeam object
            $http.delete('http://localhost:33201/api/Teams/Delete/' + vm.newTeam.teamId)
                .then(function (response) {
                    //success
                    //refresh list
                    var index = vm.teams.indexOf(team);
                    vm.teams.splice(index, 1);
                    vm.newTeam = {}; //clear form
                }, function (error) {
                    //failure
                    vm.errorMessage = "Failed to delete team: " + error;
                })
                .finally(function () {
                    vm.isBusy = false;
                });
        }
    };
})();

这是工厂:

(function() {

    "use strict";

    //creating the module, required dependencies
    //always include a dash in directive names, so they will never be confused with actual html elements
    var app = angular.module("app", ["simpleControls"]);

    //use service to inject singleton service into multiple controllers
    //service contains logic to fetch data or manipulate it
    //http://viralpatel.net/blogs/angularjs-service-factory-tutorial/
    app.factory("divisionService", function ($http) {

        var divisions = [];

        var errorMessage = "";
        var isBusy = true;

        //matched to verb, returns promise
        $http.get('http://localhost:33201/api/Divisions')
            .then(function (response) {
                //first parameter is on success
                //copy response.data to vm.divisions (could alternatively use a foreach)
                angular.copy(response.data, divisions);
            }, function (error) {
                //second parameter is on failure
                errorMessage = "Failed to load data: " + error;
            })
            .finally(function () {
                isBusy = false;
            });

        return {
            all: function () {
                return divisions;
            },
            first: function () {
                return divisions[0];
            }
        };
    });

})();

在上面的vm.editTeam方法中,行$scope.selectedDivision = team.division;不会更改下拉列表中的选定值。这是我第一次尝试这种下拉功能,所以我在这里包含了所有可能需要通过的代码,但有人可以给我任何关于如何使其工作的建议吗?

非常感谢!

3 个答案:

答案 0 :(得分:0)

我认为问题在于你没有更新控制器中的$ scope,这就是你的变量没有传播到html元素的原因。

尝试这样的事情:

function teamsController($scope, $http) {  <<< note the new $scope param

    $scope.vm.teams = 'asdfasdf';
}

答案 1 :(得分:0)

newTeam.division是一个对象。选项中使用的divCtrl.divisions是您之前定义的分割对象数组。下拉列表只能显示其divCtrl.divisions对象数组中的对象。 所以在editTeam中编辑分区会给你一个新的分区对象。

我创造了一个小小提琴。

http://jsfiddle.net/uqawcekf/1/

如果您使用第15行而不是第14行作为devisions定义,它将不再起作用。

希望这有帮助

<强>更新: 您没有从分区控制器访问错误的vm。这是来自teamsController(parent)的vm,由scope:false引起。命名有点令人困惑,因为您使用vm作为控制器范围的引用,但在controllerAs语法(divCtrl)中使用不同的名称。它们应该是一样的。但这不是问题的根源

答案 2 :(得分:0)

由于您为divisionDropdown定义了单独的控制器,因此选择模板中的ng-model='vm.newTeam.division'会引用vm中定义的divisionsController。它不会看到newTeam中定义的teamsController

您可能需要在vm.newTeam = $parent.vm.newTeam内定义divisionsController

修改

再想一想,最好使用指令的链接/编译功能来填充分区列表,并完全避免使用divisionsController