angularjsdynamicangularjs-directiveangularjs-templates

AngularJS: dynamic custom directive with multiple templates


I'm a Java developer working on a side-project. I've decided to use AngularJS to consume my RESTful webservice.

My JSON structure is following:

[
  {
    "generatorName": "name1",
    "constructorParams": [
      {
        "type": "Boolean",
        "value": "true",
      },
      {
        "type": "Integer",
        "value": "2",
      }
    ]
  },
  {
    "generatorName": "name2",
    "constructorParams": [
      {
        "type": "Integer",
        "value": "10",
      },
      {
        "type": "Integer",
        "value": "10",
      }
    ]
  }
]

My goal is to display a specific (for ex. number, text etc.) input field based on the "type" of constructor param and initialise it with a "value". So, if the first generator was selected, I'd like to have something like this:

<html>
    <select>
        <option selected="selected" value="true">Yes</option>
        <option value="false">No</option>
    </select>

    <input type="number" value="2">
<html>

I've read some threads and decided to use custom directive inside my loop:

<p ng-repeat="param in selectedGenerator.constructorParams">
      <constructor-param param="{{param}}"></constructor-param>
</p>

Here's my custom directive:

app.directive("constructorParam", function() {
    return {
        scope : {
            param : '@'
        },
        templateUrl : '/html_templates/constructor_param_template.html'
    };
});

And here's template:

<div ng-switch="{{param.type}}">
    <div ng-switch-when="Integer">
        <input type="number" ng-attr-name="{{param.type}}" min="0" ng-attr-value="{{param.value}}">
    </div>

    <div ng-switch-when="Boolean">
        <select ng-if="{{param.value}}" ng-attr-name="{{param.type}}">
            <option selected="selected" value="true">Yes</option>
            <option value="false">No</option>
        </select>

        <select ng-if="!{{param.value}}" ng-attr-name="{{param.type}}">
            <option value="true">Yes</option>
            <option selected="selected" value="false">No</option>
        </select>
    </div>

    <div ng-switch-when="String">
        <input type="text" ng-attr-name="{{param.type}}" ng-attr-value="{{param.value}}">
    </div>

    <div ng-switch-when="Double">
        <input type="number" ng-attr-name="{{param.type}}" step="0.01" min="0" ng-attr-value="{{param.value}}">
    </div>
</div>

These don't work. I can see in the Chrome developer's tools that the directive is run, but it doesn't provide any visible output. My questions are:

1) Do I pass the param object correctly in the custom directive element?

2) I'm not sure about the scope of the directive - I've also tried param : '=param' - it doesn't work either...

3) How should I read the passed object's properties in the template? I've tried: value="{{param.type}}", value={{param.type}} and ng-attr-value="{{param.value}}". None works, but there could be completely different cause to that...

4) Can I use prefix "ng-attr-" for all such element's HTML attributes as name and value?

5) My template's code is exactly what I've pasted - do I need to make it a valid HTML structure with head, body etc.? Do I have to attach <script> with AngularJS? I've done that, but once again, no change.

6) The usage scenario for the whole story is to choose a concrete generator from a drop-down list and display it's constructor params in the specified way. So it has to regenerate HTML with a generator's change. I assume that it's done in the ng-repeat loop but please confirm that.

Thank you very, very much for your input! :)


Solution

  • First of all, thank you both guys for your help! Unfortunately, I can't mark any of the given answer as correct, because I have to mixed them in order to get what I was looking for.

    I wouldn't elaborate here, let me just share with you the final code:

    <!-- container -->
    <p ng-repeat="param in selectedGenerator.constructorParams">
      <constructor-param param="param"></constructor-param>
    </p>
    
    <!-- template -->
    <div ng-switch="param.type">
        <div ng-switch-when="Integer">
            <input type="number" name={{param.type}} min="0" value={{param.value}}>
        </div>
    
        <div ng-switch-when="Boolean">
            <select ng-if="param.value" name={{param.type}}>
                <option selected="selected" value="true">Yes</option>
                <option value="false">No</option>
            </select>
    
            <select ng-if="!param.value" name={{param.type}}>
                <option value="true">Yes</option>
                <option selected="selected" value="false">No</option>
            </select>
        </div>
    
        <div ng-switch-when="String">
            <input type="text" name={{param.type}} value={{param.value}}>
        </div>
    
        <div ng-switch-when="Double">
            <input type="number" name={{param.type}} step="0.01" min="0" value={{param.value}}>
        </div>
    </div>
    

    And here's the directive, you both get it right:

    app.directive("constructorParam", function() {
      return {
        scope: {
          param: '='
        },
        templateUrl: '/html_templates/constructor_param_template.html'
      };
    });
    

    Once again - thank you very much, I wouldn't solve this problem so quickly without your help!