0

I am new to angular and trying to create my first directive.

Here is an example:

isrcorderapp.directive "isrcrow", () ->
    restrict:'A'
    controller: 'isrcorders'
    template: '<td><input id="artist" ng-model="{{artist}}"/></td>
                <td><input id="title" ng-model="{{title}}"/></td>
                <td><select id="isrctype" ng-model="{{isrctype}}" ng-options="s.type for s in recordingTypes" class="ng-pristine ng-valid"></select></td>
                <td><input id="duration" ng-model="{{duration}}"/></td>
                <td><input id="year" ng-model={{year}}/></td>
                <td><input type="button" value="Add ISRC" ng-click="AddIsrc()" class="btn btn-small btn-success" />
                    <input type="button" value="Delete" ng-click="RemoveIsrc()" class="btn btn-small btn-danger" />
                </td>'
    replace: false
    scope:
        artist:'@'
        title:'@'
        isrctype:'@'
        duration:'@'
        year:'@'
    link: (scope,element,attr) ->

This directive was working until I added the scope and ng-model in the elements.

Here is a working example before the additions were made:

http://plnkr.co/edit/oxXZlsFIDAbBCYMDOYMH?p=preview

I would like to add the values of the fields(artist.title,isrcType...) to the scope object but I keep getting errors when the web page is loaded:

Error: [$parse:syntax]

How can I fix this? What am I doing wrong here?

1 Answer 1

4

One rule of thumb with angular is you should always have a dot in ng-model.

Since you are building a collection of rows, data wise think of them first as an array of objects. Then you can use ng-repeat to generate the html from that array....not by using jQUery which doesn't belong in a controller. Adding new rows is done by pushing a new object to array and angular will update DOM accordingly. Similarly, remove from array and angular will remove the html

Here's a working version, including how to remove an object from array to remove a row.

ng-repeat will create a child scope for each row and since we are now using a dot in ng-model the object in child scope will be reference to object in array in the controller parent scope

isrcorderapp.directive("isrcrow", function(){
  return {
    restrict:'A',
    template: '<td><input  ng-model="row.artist"/></td>\
                <td><input ng-model="row.title"/></td>\
                <td><select  ng-model="row.isrctype" ng-change="setState(state)" ng-options="s.type for s in recordingTypes" class="ng-pristine ng-valid"></select></td>\
                <td><input ng-model="row.duration"/></td>\
                <td><input ng-model="row.year"/></td>\
                <td><input type="button" value="Add ISRC" ng-click="AddIsrc()" class="btn btn-small btn-success" />\
                    <input type="button" value="Delete" ng-click="RemoveIsrc(row)" class="btn btn-small btn-danger" />\
                </td>',
    replace: false
  }
});

isrcorderapp.controller("isrcorders", function($scope,$http,$compile) {
    function newItem(){
      return{
        artist:'',
        title:'',
        duration:'',
        year:'',
        isrctype:''
      }
    }
    $scope.recordingTypes = [
        {type:'A'},
        {type:'B'},
        {type:'C'},
        {type:'D'},
        {type:'E'}
        ];
      /* start array with blank object since we don't have ajax source yet*/  
     $scope.items=[newItem()] ;  

    $scope.AddIsrc = function() {
     $scope.items.push(newItem())
    };
    $scope.RemoveIsrc=function(row){
      var index=$scope.items.indexOf(row);
      $scope.items.splice(index,1)
    }    

});

In html I made adjustment of wrapping table within the controller using ng-controller and adding ng-repeat to <tr>

<tr ng-repeat="row in items" isrcrow=""></tr>

DEMO

If you haven't done so already, you should read this highly valuable post "Thinking in AngularJS" if I have a jQuery background?

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.