在angularjs中单击按钮插入/删除模板/视图

在angularjs中单击按钮插入/删除模板/视图,angularjs,angularjs-ng-repeat,angular-ui,Angularjs,Angularjs Ng Repeat,Angular Ui,在ASP.NET MVC中编程时,我习惯于使用局部视图进行CRUD操作。现在我正在使用Spring+AngularJS,我希望我能以类似的方式工作。到目前为止,通过使用angular ui router,我已经成功地完成了一些基本的创建/更新分区 例如: layout.html <!doctype html> <html lang="en" ng-app="Example"> <head> <meta charset="utf-8">

在ASP.NET MVC中编程时,我习惯于使用局部视图进行CRUD操作。现在我正在使用Spring+AngularJS,我希望我能以类似的方式工作。到目前为止,通过使用angular ui router,我已经成功地完成了一些基本的创建/更新分区

例如:

layout.html

<!doctype html>
<html lang="en" ng-app="Example">
<head>
    <meta charset="utf-8">
    <title>Test</title> 
</head>
<body>
<div class="container">
    <nav class="row">
        <ul class="nav nav-pills">
            <li ui-sref-active="active"><a ui-sref="clients">Clients</a></li>
        </ul>           
    </nav>    
</div>
<div class="container">
    <div class="row">
        <div class="col-md-12" ui-view></div>
    </div>
</div>
<script src="libs/jquery/dist/jquery.min.js"></script>
<script src="libs/angular/angular.min.js"></script>
<script src="libs/angular-ui-router/release/angular-ui-router.min.js"></script>
<script src="appjs/app.js"></script>
<script src="appjs/services.js"></script>
<script src="appjs/controllers/ClientController.js"></script>
<script src="appjs/filters.js"></script>
<script src="appjs/directives.js"></script>
</body>
</html>
ClientController.js

var ClientListController = function($scope, $http) {
    $scope.error = false;
    $scope.loading = false;

    $scope.getClientList = function() {
        $scope.loading = true;
        $http.get('clients/clientlist.json')
        .success(function(clientList) {
            $scope.clients = clientList;
            $scope.loading = false;
        })
        .error(function() {
            $scope.error = true;
            $scope.loading = false;
        });
    }

    $scope.getClientList();
};

var ClientCreateController = function($scope, $http, $location) {
    $scope.client = {};
    $scope.loading = false;

    $scope.addOrUpdate = function(client) {
        client.id = null;
        $scope.loading = true;
        $http.post('clients/createOrEdit', client)
        .success(function() {
            $scope.loading = false;
            $location.path('/clients').replace(); //redirect to index 
        });
    };
};

var ClientEditController = function($scope, $stateParams, $http, $location) {
    $scope.client = {};
    $scope.error = false;
    $scope.loading = false;

    $scope.getClientById = function(id) {
        $scope.loading = true;
        $http.get('clients/' + id + '/client.json')
        .success(function(client) {
            $scope.client = client;
            $scope.loading = false;
        })
        .error(function() {
            $scope.error = true;
            $scope.loading = false;
        });
    }

    $scope.addOrUpdate = function(client) {
        $scope.loading = true;
        $http.post('clients/createOrEdit', client)
        .success(function() {
            $scope.loading = false;
            $location.path('/clients').replace(); //redirect to index
        });
    };

    var selectedId = $stateParams.id;
    $scope.getClientById(selectedId);
}
这是我目前的设置,就其本身而言,我非常满意。然而,当我试图通过增加一点复杂性来扩展它时,我被卡住了

假设我们的客户可以有多个位置,那么现在每个客户都有一个位置列表

我想做的是创建/编辑位置的局部视图,在编辑或创建客户机时,为客户机拥有的每个现有位置显示它们、删除它们的能力以及添加新位置的能力,所有这些都在客户机创建/编辑页面上

在ASP.NETMVC中,我可以通过局部视图、BeginCollectionItem和一些jQuery来实现这一点。我应该如何处理这个问题

我尝试使用ng repeat和ng include inside,但是在尝试添加/删除位置时,ng repeat没有反映任何内容,而且我不喜欢这种方法

我假设单击按钮时没有发生任何事情的原因与我使用insertLocation方法单击按钮时在控制台中接收到的信息有关

insertLocation()
如下所示

$scope.insertLocation = function() {
    $scope.client.locations.push({});
}
并放置在创建和编辑控制器中,客户机变量也被编辑为如下所示

$scope.insertLocation = function() {
    $scope.client.locations.push({});
}
$scope.client={locations:[]}

请注意。我并不是在寻找解决这种情况的方法(尽管这会有帮助),而是更多的是对我的方法的建议。错了吗?如果是正确的心态,正确的方法是什么?

可以使用带有额外表单组的
ng repeat
渲染n个位置,以添加新位置:

<div class="form-group" ng-repeat="location in client.locations">
    <label for="address">Address:</label>
    <input type="text" model="location.address"  />
    <a ng-click="remove(location)">remove</a>
</div>

<div class="form-group">
    <label for="address">Address:</label>
    <input type="text" model="newlocation.address"  />
    <a ng-click="addLocation()">add</a>
</div>
至于“partials”,我不完全清楚您想要什么,但标记重用的角度是通过如下指令:

.controller('MyCtrl', function($scope, client) {

    $scope.client = client;
    $scope.newlocaiton = {
        address: null
    }

    $scope.remove = function(location) {
        // using underscore.js/lodash.js for remove
        _.remove($scope.client.locations, location);
    };

    $scope.addLocation = function() {
        // ignoring whatever you might need to do calling 
        // server to persist etc. Just adding to client
        $scope.client.locations.push($scope.newlocation);
    };
})
.directive('LocationForm', function() {
    return {
        restrict: 'EA',
        scope: {
            location: '=',
            onRemove: '='
        },
        templateUrl: 'location.edit.html',
        link: function(scope, el, attr) {
            // omitted
        }
    }
})
location.edit.html

<label for="address">Address:</label>
<input type="text" model="location.address"  />
<a ng-click="remove(location)">remove</a>
地址:

  • n个位置可以使用带有额外表单组的
    ng repeat
    渲染,用于添加新位置:

    <div class="form-group" ng-repeat="location in client.locations">
        <label for="address">Address:</label>
        <input type="text" model="location.address"  />
        <a ng-click="remove(location)">remove</a>
    </div>
    
    <div class="form-group">
        <label for="address">Address:</label>
        <input type="text" model="newlocation.address"  />
        <a ng-click="addLocation()">add</a>
    </div>
    
    至于“partials”,我不完全清楚您想要什么,但标记重用的角度是通过如下指令:

    .controller('MyCtrl', function($scope, client) {
    
        $scope.client = client;
        $scope.newlocaiton = {
            address: null
        }
    
        $scope.remove = function(location) {
            // using underscore.js/lodash.js for remove
            _.remove($scope.client.locations, location);
        };
    
        $scope.addLocation = function() {
            // ignoring whatever you might need to do calling 
            // server to persist etc. Just adding to client
            $scope.client.locations.push($scope.newlocation);
        };
    })
    
    .directive('LocationForm', function() {
        return {
            restrict: 'EA',
            scope: {
                location: '=',
                onRemove: '='
            },
            templateUrl: 'location.edit.html',
            link: function(scope, el, attr) {
                // omitted
            }
        }
    })
    
    location.edit.html

    <label for="address">Address:</label>
    <input type="text" model="location.address"  />
    <a ng-click="remove(location)">remove</a>
    
    地址:
    
    

  • 为了完整起见,这里是我的解决方案:

    为了使事情更简单,我将客户机位置之间的多对一关系替换为项目及其子项目之间的多对一关系

    因此,按照完成顺序:

  • 我已经创建了子项输入的“部分”html(可以说是“可重用”的模板)。它看起来是这样的:
    \u SubItem.html
    (我决定重用ASP.NET MVC方法,在部分前面加下划线)

    看起来很简单。下面是在
    index.html

    <div class="col-xs-4" ng-repeat="subitem in item.subitems track by $index">
      <sub-item-partial></sub-item-partial>
    </div>
    
    
    

  • 这基本上就是部分指令。项控制器包含用于创建和删除子项的方法。另外,您可能会注意到,ng repeat是通过$index
    跟踪的
    ed
    。这样做的原因是,我希望能够一次创建n个数量的子项,填充它们并将它们传递给服务器。由于默认情况下,
    ng repeat
    使用对象本身而不是其索引,因此不允许重复条目

    为了完整起见,这里是我的解决方案:

    为了使事情更简单,我将客户机位置之间的多对一关系替换为项目及其子项目之间的多对一关系

    因此,按照完成顺序:

  • 我已经创建了子项输入的“部分”html(可以说是“可重用”的模板)。它看起来是这样的:
    \u SubItem.html
    (我决定重用ASP.NET MVC方法,在部分前面加下划线)

    看起来很简单。下面是在
    index.html

    <div class="col-xs-4" ng-repeat="subitem in item.subitems track by $index">
      <sub-item-partial></sub-item-partial>
    </div>
    
    
    

  • 这基本上就是部分指令。项控制器包含用于创建和删除子项的方法。另外,您可能会注意到,ng repeat是通过$index
    跟踪的
    ed
    。这样做的原因是,我希望能够一次创建n个数量的子项,填充它们并将它们传递给服务器。由于默认情况下,
    ng repeat
    使用对象本身而不是其索引,因此不允许重复条目

    我对布局有点困惑,为什么会有CreateOREdit视图?我想创建一个创建视图来创建客户端,编辑用于编辑,createoredit做什么?@Rohit创建和编辑表单都有相同的输入,唯一的区别是编辑还有一个隐藏的输入来存储编辑项的id。因此createOrEdit包含创建和编辑操作所共有的表单输入。它的目的是尽可能保持干燥原则。您的意思是重复第二个
    表单组
    1次或更多次?(n个位置+1个空用于添加新位置或类似的东西?@craigb位置是一个具有3个属性的对象。我希望有一个部分视图,其中包含每个属性和1的表单输入。对客户端拥有的每个现有位置重复n次,并用相应的数据(以及隐藏的id输入)填充,2。按+按钮添加相同的部分,没有隐藏的id输入和空输入。我对布局有点困惑,为什么会有CreateOREdit视图?我想创建一个用于创建客户端的create视图,编辑用于编辑,createoredit做什么?@Rohit create和edit表单都有相同的输入,唯一的区别是edit还有一个隐藏的输入来存储edi的id
    <div class="col-xs-4" ng-repeat="subitem in item.subitems track by $index">
      <sub-item-partial></sub-item-partial>
    </div>