AngularJS 从 ng-repeat 创建的表单中选择值

AngularJS Selecting values from form created by ng-repeat

首先:抱歉,如果这些片段有很多标签 (:

大家好!

目前我正在开发一个基于 AngularJS 的应用程序。该应用程序通过 Prestashop Webservice 建立了数据库连接。我正在尝试编辑数据库中的内容。我认为这个例子会更清楚。

总结
Web 服务可用于使用现有的 prestashop 安装创建 link。 link 本身是一个用于访问数据库的 REST API。有了这些信息,我们就可以从数据库中获取、设置、编辑和删除数据。请参阅以下客户 table 的示例:

<?php

require_once('.././PSWebServiceLibrary.php');

/**
* get information from PrestaShop
*/
  
$webService = new PrestaShopWebservice($url, $key, $debug);

$opt = array(
 "resource" => "customers",
 "display" => "full",
);

$jsonUrl = ($webService->get( $opt ));

//json encode it
$json = json_encode($jsonUrl);


echo($json);

?>

本例中所有变量的定义如下:

下一步是编译 app.js 中的 JSON 数据,以便我们能够 select 并显示查询的不同部分,请参见下面的示例:

myApp.controller('CustomerController', function($scope, $http) {
    $http.get('config/get/getCustomers.php').then(function (response) {
        $scope.customers = response.data.customers.customer
    });
});

现在我们能够 select JSON 数据的不同部分。我们可以在 HTML 中结合 ng-controllerng-repeatng-bind 显示这些数据。请参阅以下示例:

<div ng-controller="CustomerController" class="col-lg-12">
  <div class="row listrow" ng-repeat="customer in customers | orderBy: customer.id">
      <div class="col-lg-8">
        <p class="customer" ng-bind="customer.id + ' ' + customer.firstname + ' ' + customer.lastname">   </p>
      </div>
  </div>
</div>

在这种情况下,我们将重复 JSON 数据中的客户 ID、名字和姓氏。输出将是这样的:

<div ng-controller="CustomerController" class="col-lg-12">
  <div class="row listrow" ng-repeat="customer in customers | orderBy: customer.id">
      <div class="col-lg-8">
        <p class="customer">1 John Doe</p>
        <p class="customer">2 John Don't</p>
        <p class="customer">3 John Does</p>
      </div>
  </div>
</div>

到目前为止一切正常,接下来我添加的是一个编辑按钮,这将打开一个带有表单的模式。该表单将加载与客户 ID 对应的所有客户信息。这些信息包括地址、phone 号码等。请参见下面的示例:

<div class="row listrow" ng-repeat="customer in customers | orderBy: customer.id">
  <div class="col-lg-8">
   <p class="customer" ng-bind="customer.id + ' ' + customer.firstname + ' ' + customer.lastname"></p>
  </div>
  <div class="col-lg-2">
   <a href="" data-toggle="modal" data-target=".bd-example-modal-sm{{customer.id}}">
    {{'Wijzig' | translate }}
   </a>
  </div>
  <div ng-if="customer.id == address.id" ng-repeat="address in addresses" class="modal fade bd-example-modal-sm{{customer.id}}"  tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel" aria-hidden="true">
   <div class="modal-dialog modal-lg">
    <div class="modal-content customer-modal">
     <div class="modal-header product-modal-header no-border">
      <div class="container">
       <div class="row">
        <form ng-controller="CustomerController" class="bottomborderinput margin-t-25 col-xs-12 col-sm-12 col-md-12 col-lg-12 col-xl-12">
         <div class="form-group row justify-content-between">
          <div>
           <label class="d-flex">{{ 'Customer_id' | translate }}</label>
           <input title="customer_id" type="number" name="customer_id" id="customer_id" class="form-control" aria-describedby="" ng-value="customer.id">
          </div>
          <div class="col-6">
           <label class="d-flex">{{ 'Voornaam' | translate }}</label>
           <input title="Voornaam" type="text" name="editFirstname" id="firstname" class="form-control" aria-describedby="" ng-value="customer.firstname">
          </div>
          <div class="col-6">
           <label class="d-flex">{{ 'Achternaam' | translate }}</label>
           <input title="Achternaam" type="text" name="editLastname" class="form-control" aria-describedby="" ng-value="customer.lastname">
          </div>
         </div>
         <div class="form-group row justify-content-between">
          <div class="col-12">
           <label class="d-flex">{{ 'Email' | translate }}</label>
           <input title="Email" type="email" name="editEmail" class="form-control" aria-describedby="" ng-value="customer.email">
          </div>
         </div>
         <!-- Addresscontroller for address table -> DB -->
         <div ng-if="customer.id == address.id" ng-repeat="address in addresses" class="form-group row justify-content-between">
          <div class="col-12">
           <label class="d-flex">{{ 'Straat en huisnummer' | translate }}</label>
           <input title="Straat en huisnummer" type="text" name="editResidential" class="form-control" aria-describedby="" ng-value="address.address1">
          </div>
         </div>
         <div ng-if="customer.id == address.id" ng-repeat="address in addresses" class="form-group row justify-content-between">
          <div class="col-6">
           <label class="d-flex">{{ 'Postcode' | translate }}</label>
           <input title="Postcode" type="text" name="editArea_code" class="form-control" aria-describedby="" ng-value="address.postcode">
          </div>
          <div class="col-6">
           <label class="d-flex">{{ 'Plaats' | translate }}</label>
           <input title="Plaats" type="text" name="editCity" class="form-control" aria-describedby="" ng-value="address.city">
          </div>
         </div>
         <!-- ID Lang omzetten naar text language -->
         <div class="form-group row justify-content-between">
          <div class="col-6">
           <label class="d-flex">{{ 'Land' | translate }}</label>
           <input title="Land" type="text" name="editCountry" class="form-control" aria-describedby="" ng-value="customer.id_lang">
          </div>
         <!-- Address db -->
          <div ng-if="customer.id == address.id" ng-repeat="address in addresses" class="col-6">
           <label class="d-flex">{{ 'Telefoon nummer' | translate }}</label>
           <input title="Telefoon nummer" type="tel" name="editPhone" class="form-control" aria-describedby="" ng-value="address.phone">
          </div>
         </div>
         <div ng-if="customer.id == address.id" ng-repeat="address in addresses" class="form-group row justify-content-between">
          <div class="col-6">
           <label class="d-flex">{{ 'Bedrijfsnaam' | translate }}</label>
           <input title="bedrijfsnaam" type="text" name="editCompany_name" class="form-control" aria-describedby="" ng-value="address.company">
          </div>
         <!-- Address DB -->
          <div class="col-6">
           <label class="d-flex">{{ 'BTW nummer' | translate }}</label>
           <input title="BTW - nummer" type="text" name="editVat_number" class="form-control" aria-describedby="" ng-value="address.vat_number">
          </div>
         </div>
         <div ng-repeat-end class="form-group row justify-content-between">
          <div class="col-12">
           <label class="d-flex">{{ 'Klantgroep' | translate }}</label>
           <input title="Klantroep" type="text" name="editKlantgroep" class="form-control" aria-describedby="" ng-value="customer.id_default_group">
          </div>
         </div>
         <div class="form-group text-center">
          <button type="submit" ng-click="EditCustomer()" class="defaultbutton margin-t-50">
           <svg class="align-middle float-left " width="27" height="25" viewBox="13 12 27 21" xmlns="http://www.w3.org/2000/svg">
            <path d="M23.065 32.28c-.287 0-.575-.124-.8-.373l-8.182-9.057c-.47-.52-.494-1.394-.052-1.95.443-.554 1.183-.58 1.653-.06l7.365 8.153 14.395-16.6c.46-.532 1.2-.523 1.652.022.452.544.443 1.416-.018 1.95L23.882 31.886c-.227.262-.522.393-.817.393z" fill="#FFF" fill-rule="evenodd"/>
           </svg>{{ 'Klant opslaan' | translate }}
          </button>
         </div>
        </form>
       </div>
      </div>
     </div>
     <div class="modal-footer no-border product-modal-footer">
      <a data-dismiss="modal">{{ 'Sluit' | translate }}</a>
     </div>
    </div>
   </div>
  </div>

关于上述代码段的简短摘要

"wijzig" link 可以翻译为编辑客户。 on-click 模式将被打开。在打开模式之前,class 将被 ID 过滤,以便从数据库请求正确的信息。

因此,如果客户“3”住在 smurfs village:3,则过滤器将从数据库中的地址 table 获取此信息。

现在的问题
问题不在于 selecting 数据,而在于更新数据。如您所见,数据是 select 从数据库中提取并作为值加载到表单中的。然后用户可以编辑这些值。就像有人从一所房子搬到另一所房子,所以他的地址必须更新。表格如下:

<form ng-controller="CustomerController" class="bottomborderinput margin-t-25 col-xs-12 col-sm-12 col-md-12 col-lg-12 col-xl-12">
         <div class="form-group row justify-content-between">
          <div>
           <label class="d-flex">{{ 'Customer_id' | translate }}</label>
           <input title="customer_id" type="number" name="customer_id" id="customer_id" class="form-control" aria-describedby="" ng-value="customer.id">
          </div>
          <div class="col-6">
           <label class="d-flex">{{ 'Voornaam' | translate }}</label>
           <input title="Voornaam" type="text" name="editFirstname" id="firstname" class="form-control" aria-describedby="" ng-value="customer.firstname">
          </div>
          <div class="col-6">
           <label class="d-flex">{{ 'Achternaam' | translate }}</label>
           <input title="Achternaam" type="text" name="editLastname" class="form-control" aria-describedby="" ng-value="customer.lastname">
          </div>
         </div>
         <div class="form-group row justify-content-between">
          <div class="col-12">
           <label class="d-flex">{{ 'Email' | translate }}</label>
           <input title="Email" type="email" name="editEmail" class="form-control" aria-describedby="" ng-value="customer.email">
          </div>
         </div>
         <!-- Addresscontroller for address table -> DB -->
         <div ng-if="customer.id == address.id" ng-repeat="address in addresses" class="form-group row justify-content-between">
          <div class="col-12">
           <label class="d-flex">{{ 'Straat en huisnummer' | translate }}</label>
           <input title="Straat en huisnummer" type="text" name="editResidential" class="form-control" aria-describedby="" ng-value="address.address1">
          </div>
         </div>
         <div ng-if="customer.id == address.id" ng-repeat="address in addresses" class="form-group row justify-content-between">
          <div class="col-6">
           <label class="d-flex">{{ 'Postcode' | translate }}</label>
           <input title="Postcode" type="text" name="editArea_code" class="form-control" aria-describedby="" ng-value="address.postcode">
          </div>
          <div class="col-6">
           <label class="d-flex">{{ 'Plaats' | translate }}</label>
           <input title="Plaats" type="text" name="editCity" class="form-control" aria-describedby="" ng-value="address.city">
          </div>
         </div>
         <!-- ID Lang omzetten naar text language -->
         <div class="form-group row justify-content-between">
          <div class="col-6">
           <label class="d-flex">{{ 'Land' | translate }}</label>
           <input title="Land" type="text" name="editCountry" class="form-control" aria-describedby="" ng-value="customer.id_lang">
          </div>
         <!-- Address db -->
          <div ng-if="customer.id == address.id" ng-repeat="address in addresses" class="col-6">
           <label class="d-flex">{{ 'Telefoon nummer' | translate }}</label>
           <input title="Telefoon nummer" type="tel" name="editPhone" class="form-control" aria-describedby="" ng-value="address.phone">
          </div>
         </div>
         <div ng-if="customer.id == address.id" ng-repeat="address in addresses" class="form-group row justify-content-between">
          <div class="col-6">
           <label class="d-flex">{{ 'Bedrijfsnaam' | translate }}</label>
           <input title="bedrijfsnaam" type="text" name="editCompany_name" class="form-control" aria-describedby="" ng-value="address.company">
          </div>
         <!-- Address DB -->
          <div class="col-6">
           <label class="d-flex">{{ 'BTW nummer' | translate }}</label>
           <input title="BTW - nummer" type="text" name="editVat_number" class="form-control" aria-describedby="" ng-value="address.vat_number">
          </div>
         </div>
         <div ng-repeat-end class="form-group row justify-content-between">
          <div class="col-12">
           <label class="d-flex">{{ 'Klantgroep' | translate }}</label>
           <input title="Klantroep" type="text" name="editKlantgroep" class="form-control" aria-describedby="" ng-value="customer.id_default_group">
          </div>
         </div>
         <div class="form-group text-center">
          <button type="submit" ng-click="EditCustomer()" class="defaultbutton margin-t-50">
           <svg class="align-middle float-left " width="27" height="25" viewBox="13 12 27 21" xmlns="http://www.w3.org/2000/svg">
            <path d="M23.065 32.28c-.287 0-.575-.124-.8-.373l-8.182-9.057c-.47-.52-.494-1.394-.052-1.95.443-.554 1.183-.58 1.653-.06l7.365 8.153 14.395-16.6c.46-.532 1.2-.523 1.652.022.452.544.443 1.416-.018 1.95L23.882 31.886c-.227.262-.522.393-.817.393z" fill="#FFF" fill-rule="evenodd"/>
           </svg>{{ 'Klant opslaan' | translate }}
          </button>
         </div>
        </form>

app.js中的ng-click函数:

$scope.EditCustomer = function() {
        var customer_id = $('input[name="customer_id"]').val();
        var firstname = $('input[name="editFirstname"]').val();
        var lastname = $('input[name="editLastname"]').val();
        var email = $('input[name="editEmail"]').val();
        var residential = $('input[name="editResidential"]').val();
        var area_code = $('input[name="editArea_code"]').val();
        var city = $('input[name="editCity"]').val();
        var country = $('input[name="editCountry"]').val();
        var phone = $('input[name="editPhone"]').val();
        var company_name = $('input[name="editCompany_name"]').val();
        var vat_number = $('input[name="editVatnumber"]').val();
        var customer_group = $('input[name="editCustomer_group"]').val();


        $.ajax({
            type:'POST',
            data:{customer_id:customer_id, firstname:firstname, lastname:lastname,email:email, residential:residential, area_code:area_code, city:city, country:country, phone:phone, company_name:company_name,vat_number:vat_number, customer_group:customer_group},
            url:"config/edit/editCustomer.php", // PHP Page URL To php code saving the input to the database
            success : function(response) {
                alert(response.msg);
            }
        })
    };

我知道 $.ajax 应该更改为 $http.post

对应的php更新文件:

<?php
// Here we define constants /!\ You need to replace this parameters
define('DEBUG', true);
require_once "../PSWebServiceLibrary.php";

// Here we use the WebService to get the schema of "customers" resource
$webService = new PrestaShopWebservice($url, $key, DEBUG);

// Edit customer.
// Request the input field values.

$customer_id = $_REQUEST['customer_id'];
$customer_firstname = $_REQUEST['firstname'];
$customer_lastname = $_REQUEST['lastname'];
$customer_email = $_REQUEST['email'];
$customer_residential = $_REQUEST['residential'];
$customer_area_code = $_REQUEST['area_code'];
$customer_city = $_REQUEST['city'];
$customer_country = $_REQUEST['country'];
$customer_phone = $_REQUEST['phone'];
$customer_company_name = $_REQUEST['company_name'];
$customer_vat_number = $_REQUEST['vat_number'];
$customer_group = $_REQUEST['customer_group'];

$opt = $webService->get(array(
        "resource" => "customers",
        "display" => "full",
        "filter[id]" => $customer_id
    ));
$resource = $opt->children()->children();
$resource->id = $customer_id;
$resource->id_shop = 1;
$resource->passwd = "";
$resource->id_default_group = $customer_group;
$resource->id_lang = $customer_country;
$resource->firstname = $customer_firstname;
$resource->lastname = $customer_lastname;
$resource->email = $customer_email;
$resource->date_add = "";

$xml = $opt->asXML();    // all of it!
$ret = $webService->edit(array(
    'resource' => 'customers',
    'id' => $customer_id,
    'putXml' => $xml
));

$opt1 = $webService->get(array(
    'resource' => 'addresses',
    'display' => 'full',
    'filter[id]' => $customer_id
));
$resource = $opt1->children()->children();
$resource->id = $customer_id;
$resource->company = $customer_company_name;
$resource->lastname = $customer_lastname;
$resource->firstname = $customer_firstname;
$resource->id_country = $customer_country;
$resource->alias = "mijn adres";
$resource->address1 = $customer_residential;
$resource->postcode = $customer_area_code;
$resource->city = $customer_city;
$resource->phone_mobile = $customer_phone;
$resource->vat_number = $customer_vat_number;

$xml1 = $opt1->asXML();    // all of it!
$ret1 = $webService->edit(array('resource' => 'addresses', 'id' => $customer_id, 'putXml' => $xml1));

所以实际问题是,在更新客户时,我总是检索 id = 1。在过滤器中,这是由于第一个出现的 <form> 是 id=1。由于所有输入名称都相同 JS 将获取第一个,在本例中为 id = 1.

因此,对于使用 id = 1 编辑客户。一切正常,但是当我尝试使用 id = 3 编辑客户时,第一个 ID 仍然是 selected。

我的问题是:有没有办法以更适当的方式过滤它,以便 select 编辑和编辑具有正确 ID 的正确表单?

我希望一切都清楚,如果不清楚,请告诉我。

提前致谢!

首先,我创建了一个控制器来处理逻辑。我假设你有类似的布局。

为了胆量,在您的 ng-repeat 上,为每个 <li>(或其他类似元素)创建一个 ng-clickng-click 上的方法应传入 customer 的值(或您在每次迭代中获得的单个值)

因此,单击任何 <li> 将依次引用创建时使用的同一模型对象。

(function() {
  var app = angular.module("cus", []);

  var CustomerController = function() {
    var vm = this;
    vm.Customers = [{ // Should be like Edit #2
        name: "Joe",
        age: 25,
        gender: "Male"
      },
      {
        name: "Lisa",
        age: 18,
        gender: "Female"
      },
      {
        name: "Foobar",
        age: 89,
        gender: "Dog"
      },
    ];
    vm.showInfo = function(customer) {
      console.log(customer.name + " is a " + customer.age + " year old " + customer.gender);
    }
    vm.submitInfo = function(customer) { // This is your $EditCustomer()
        console.log("Submitting " + customer.name + " to database.");
        console.log("Saving age as: " + customer.age);
        console.log("Saving gender as: " + customer.gender);
        console.log("Successfully saved " + customer.name + "!");
    }
  }

  app.controller("CustomerController", [CustomerController]);
})();
<html>

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>

<body ng-app="cus">
  <div ng-controller="CustomerController as vm">
    <ul ng-repeat="customer in vm.Customers">
      <li ng-click="vm.showInfo(customer);">{{ customer.name }}</li>
      <li ng-click="vm.showInfo(customer);">{{ customer.age }}</li>
      <li ng-click="vm.showInfo(customer);">{{ customer.gender }}</li>
    </ul>

    <div class="form-group" ng-repeat="customer in vm.Customers"> <!-- This is your form-->
      <ng-form name="userFieldForm">
        <label>{{ customer.name }}'s Age</label>
        <input type="text" class="form-control" name="email" ng-model="customer.age">
        <label>{{ customer.name }}'s Gender</label>
        <input type="text" class="form-control" name="gender" ng-model="customer.gender">
        <button type="submit" ng-click="vm.submitInfo(customer)">Submit</button>
      </ng-form>
    </div>
  </div>
</body>

</html>

在您的情况下,您希望在 $scope.EditCustomer 上传递 customer 的值。

所以会变成这样,

$scope.EditCustomer = function(customer) {
    var customer_id = customer.id;
    var firstname = customer.firstName;
    var lastname = customer.lastName;
    var email = customer.email;
    ...


    $.ajax({
        type:'POST',
        data:{customer_id:customer_id, firstname:firstname, lastname:lastname,email:email, residential:residential, area_code:area_code, city:city, country:country, phone:phone, company_name:company_name,vat_number:vat_number, customer_group:customer_group},
        url:"config/edit/editCustomer.php", // PHP Page URL To php code saving the input to the database
        success : function(response) {
            alert(response.msg);
        }
    })
};

编辑

我更新了它,在 ng-repeat 中创建了一个 ng-form。为每个 customer in Customers 创建一个表单。将 <button>ng-click="submitInfo(customer)" 放在一起将使您将该对象传递到方法中,以便信息从 ng-repeat 创建的表单获取到解析数据的方法在表格中保存。

编辑 #2

而不只是设置 $scope.customers = response.data.customers.customer, 做成这样,

myApp.controller('CustomerController', function($scope, $http) {
    vm.Customers =  [];
    var responseData; // Holds the JSON response
    $http.get('config/get/getCustomers.php').then(function (response) {
        responseData = response.data.customers; // response.data.customers.customer;
        for(var cus in responseData) { // Filling up vm.Customers with data from response
            vm.Customers.push(cus);
        }
    });
});

这样,您将在从响应中获取 Customer 对象后对其进行填充。现在,如果您将它们与提到的所有其他内容联系起来,它应该可以正常工作。