ng-repeat and ng-controller on the same DOM element

前端 未结 2 441
萌比男神i
萌比男神i 2021-02-06 03:54

Can we attach ng-controller and ng-repeat to the same DOM element? Fiddle

Here is the HTML:

相关标签:
2条回答
  • 2021-02-06 04:33

    What I want is the variable selected should be unique for each scope.

    Yes you can.

    Multiple controller way

    You can create root controller mainController and add to your model users new controller per user.

    After that, call new controller in ng-repeat as ng-controller="user.ctrl"

    Demo Fiddle

    I would write something like:

    HTML

    <div ng-controller="mainController">
        <table>
            <tbody ng-repeat="user in users" ng-controller="user.ctrl" ng-click="toggleSelectedUser()" ng-switch on="isSelectedUser()">
                <tr>
                    <td>{{user.name}}</td>
                    <td>{{user.email}}</td>
                </tr>
                <tr ng-switch-when="true">
                    <td colspan="2" style="padding-left: 10px">{{user.desc}}</td>
                </tr>
            </tbody>
        </table>
    </div>
    

    JS

    var fessmodule = angular.module('myModule', []);
    
    fessmodule.controller('mainController', function ($scope) {
        $scope.users = [{
            ctrl: fooCtrlA,
            name: "AAAAA",
            email: "a2009@gmail.com",
            desc: "Description about AAAA"
        }, {
            ctrl: fooCtrlB,
            name: "BBBBB",
            email: "b2009@gmail.com",
            desc: "Description about BBBBB"
        }, {
            ctrl: fooCtrlC,
            name: "CCCCC",
            email: "c2009@gmail.com",
            desc: "Description about CCCC"
        }];
    });
    
    fessmodule.$inject = ['$scope'];
    
    function fooCtrlA($scope) {
        $scope.selected = true;
        $scope.toggleSelectedUser = function () {
            $scope.selected = !$scope.selected;
        };
        $scope.isSelectedUser = function () {
            return $scope.selected;
        };
    }
    
    function fooCtrlB($scope) {
        $scope.selected = false;
        $scope.toggleSelectedUser = function () {
            $scope.selected = !$scope.selected;
        };
        $scope.isSelectedUser = function () {
            return $scope.selected;
        };
    }
    
    function fooCtrlC($scope) {
        $scope.selected = false;
        $scope.toggleSelectedUser = function () {
            $scope.selected = !$scope.selected;
        };
        $scope.isSelectedUser = function () {
            return $scope.selected;
        };
    }
    

    However you can see we have code duplicate!!. Each "child" controller has the same logic:

        $scope.selected = false;
        $scope.toggleSelectedUser = function () {
            $scope.selected = !$scope.selected;
        };
        $scope.isSelectedUser = function () {
            return $scope.selected;
        };
    

    If you want to make your code work, I would use ng-model.

    Other way with ng-model

    Demo 2 Fiddle

    HTML

    <tbody ng-repeat="user in users" ng-click="toggleSelectedUser(user)" ng-switch on="isSelectedUser(user)">
                <tr ng-model="user">
                    <td>{{user.name}}</td>
                    <td>{{user.email}}</td>
                </tr>
                <tr ng-switch-when="true">
                    <td colspan="2" style="padding-left: 10px">{{user.desc}}</td>
                </tr>
            </tbody>
    

    and controller with modified model:

    var fessmodule = angular.module('myModule', []);
    
    fessmodule.controller('mainController', function ($scope) {
        $scope.users = [{
            selected: false,
            name: "AAAAA",
            email: "a2009@gmail.com",
            desc: "Description about AAAA"
        }, {
            selected: false,
            name: "BBBBB",
            email: "b2009@gmail.com",
            desc: "Description about BBBBB"
        }, {
            selected: false,
            name: "CCCCC",
            email: "c2009@gmail.com",
            desc: "Description about CCCC"
        }];
    
    
        $scope.toggleSelectedUser = function (user) {
            user.selected = !user.selected;
        };
        $scope.isSelectedUser = function (user) {
            return user.selected;
        };
    });
    
    0 讨论(0)
  • 2021-02-06 04:44

    You should break your controller into UserListController and UserController. The list of users should be part of UserListController and the each item can be managed by UserController

    Something like

    <table ng-controller='UserListController'>
            <tbody ng-controller="UserController" ng-repeat="user in users" ng-click="toggleSelectedUser()" ng-switch on="isSelectedUser()" ng-init="user=user">
    

    So the user controller becomes

    angular.module("myApp", [])     
        .controller("UserController", ["$scope", function($scope) {
            $scope.selected = false;
    
            $scope.toggleSelectedUser = function() {
                $scope.user.selected = !$scope.selected;
            };
    
            $scope.isSelectedUser = function() {
                return $scope.user.selected;
            };
        }]);
    
    0 讨论(0)
提交回复
热议问题