简体   繁体   中英

How do I pass a variable into an AngularJS template

I am using the html element to call a template that contains inputs. This gets used several times on the page. How can I differentiate between them using an attribute and/or index, to populate each respective ng-model?

JS Code:

angular.module('myModule').directive('address', function () {
  return{
    restrict: 'E',
    replace: true,
    templateUrl: '/address.tpl.html',
    scope: {
      address: '=',
      form: '='
    },
    link: function (scope, el, attrs) {
      scope.isRequired = attrs.optional === undefined;
    }
  };
});

Main page HTML code:

<p>My Address</p>      <address></address>
<p>Extra Address 1</p> <address></address>
<p>Extra Address 2</p> <address></address>
<p>Your Address</p>    <address></address>

There can be any number of extra addresses.

Address.tpl.html HTML code:

  <ng-form name="addressForm">
    <label>Postcode:</label> 
    <input name="postcode" type="text" ng-model="address.postcode"/>
  </ng-form>

Obviously, this doesn't help me get to the values, as each instance of the input will have the same ng-model: $scope.address.postcode. Ideally, I am looking to put an attribute in the address element that will mean I can define the name of the ng-model as address.myAddress.postcode or address.extraAddress6.postcode.

EDIT: Now that I have the answer, I've noticed that the necessary code is already in the JS file. That address: '=' was the data-binding I needed.

Main page HTML code (New code):

<p>My Address</p>      <address address="my"></address>
<p>Extra Address 1</p> <address address="extra1"></address>
<p>Extra Address 2</p> <address address="extra2"></address>
<p>Your Address</p>    <address address="your"></address>

I can now access the scope value of ng-model="address.postcode" using $scope.my.postcode and $scope.extra1.postcode, etc etc.

Can you add an atrribute to each address tag and use that to differentiate them?

    <p>My Address</p>      <address type="'my'"></address>
    <p>Extra Address 1</p> <address type="'extra1'"></address>
    <p>Extra Address 2</p> <address type="'extra2'"></address>
    <p>Your Address</p>    <address type="'your'"></address>

scope: {
      address: '=',
      form: '=',
      type: '&'

    },
    link: function (scope, el, attrs) {
      scope.isRequired = attrs.optional === undefined;
      switch(attrs.type) {
          case 'my':
          ...

You could use ng-repeat in this instance. It sounds like you want an arbitrary amount of extra addresses. So maybe this will help:

$scope.extraAddresses = [ 'address1', 'address2', 'address3', 'address4' ];

Then in your HTML:

<p ng-repeat="address in extraAddresses">{{address}}</p>

If you want the addresses to contain extra data. Update the model to be an array of objects:

$scope.extraAddresses = [ 
   {
      "address": "address1",
      "postalcode": "06060"
   }
];

Then in your HTML:

<p ng-repeat="address in extraAddresses">{{address.address}}, {{address.postalcode}}</p>

In other words, basically treat everything as an array of objects and iterate through them using ng-repeat .

If I were you, I would start by putting all of your initialization data into a single JSON object. Perhaps you could have:

ADDRESS_JSON_OBJECT = [
    { address1: "1234 Fake St.", country: "Blahnada" },
    { address1: "1234 Fake St.", country: "Blahmerica" }
];

In your application module define a 'value' like so:

myApplication = angular.module( ... ).value('addresses', ADDRESS_JSON_OBJECT)

Your address controller will now depend on this data:

myControllerModule = 
    angular.module( ... )
    .controller('AddressController', 
        ['$scope', 'addresses', function ($scope, addresses) {
        //don't do the init here....
        }
    );

Now in each of your HTML templates you can init the values using the 'ng-init' predicate:

<ng-form name="addressForm">
    <label>Postcode:</label> 
    <input ng-init="address = addresses[0]" name="postcode" type="text" ng-model="address.postcode"/>
</ng-form>

I haven't actually tested this code, but I believe this general idea would work. I've used the ng-init to bootstrap inputs before.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM