Reputation: 356
I'm relatively new to angular and this is my first involved directive and I'm a little lost. I'm trying to create a re-usable list of items on separate tabs in my app. The list acts the same with the exception of how the items are displayed (handled by separate partials). I'm passing in attributes of many different types into the scope and I'm trying several different things based on what I've been reading. No matter what I've tried so far, I'm still having issues with the attributes binding correctly.
Below is my code and I'll try to explain it as best as possible, hopefully someone can tell me where I went wrong. The only things that appear to have bound correctly are the strings, the objects and functions are missing.
UPDATE: Turns out I needed to bind $scope.currentPage to the directive scope. Now ng-repeat is running, but other parts of the page that require access to the controller scope aren't working. I've updated the code below and continue looking into how to give access to the template.
Directive
var app = angular.module('main');
app.directive('itemList', function(){
var linkFunction = function(scope, element, attributes){
scope.$watch("query.value", function(){
scope.filterFunction(); //pretty sure this never gets called on search
});
}
return {
restrict: 'E',
replace: 'true',
templateUrl: 'partials/directives/list-tab.html',
link: linkFunction,
scope: {
filterFunction: "&filterFunction",
searchPlaceholder: "@searchPlaceholder",
pagedItems: "=pagedItems",
clickFunction: "&clickFunction",
classString: "@classString",
infoTemplate: "@template",
currentPage: "=currentPage"
}
}
});
index.html
//pagedCars is an array of nested objects that gets used by the template to display the information
//filterCars is a function
//carSelected is a function
<div class="available-items">
<item-list filter-function="filterCars" search-placeholder="Search Cars" paged-items="pagedCars" current-page="currentPage" click-function="carSelected" class-string="car.carId==selectedCar.carId?'selected':''" template="'partials/cars/cars-template.html'"></item-list>
</div>
list-tab.html
<div class="form-group">
<div class="search-field">
<label for="searchField" id="searchLabel">Search</label><br/>
<input type="text" ng-model="query.value" placeholder="{{searchPlaceholder}}"/>
</div>
<table class="table table-hover>
<tbody>
//currentPage is on the controller scope there's a separate control that allows the user to page through the pagedItems by updating the currentPage which would be reflected here
<tr ng-repeat="item in pagedItems[currentPage]" ng-click="clickFunction($index) ng-class="classString">
<td ng-include="infoTemplate"></td>
</tr>
</tbody>
</table>
</div>
cars-template.html
<div class="row form-inline" id="{{item.carId}}">
<div class="col-md-2">
//this uses a method on the controller scope to format the url
<img ng-src="{{retrieveIcon(item.iconUrl)}}" height="75px" width="75px"/>
<div class="col-md-10">
<div details-pane" id="carDetails" ng-include="'partials/cars/car-full-details.html'"></div>
<div class="item-title">{{item.name}}</div>
//the rest is just a table with more information about the item. item.description, item.mileage, etc...
</div>
</div>
Upvotes: 1
Views: 787
Reputation: 89
Try passing through your functions with their parentheses
<div class="available-items">
<item-list filter-function="filterCars()" search-placeholder="Search Cars" paged-items="pagedCars" click-function="carSelected()" class-string="car.carId==selectedCar.carId?'selected':''" template="'partials/cars/cars-template.html'"></item-list>
</div>
Also FYI if your variable has the same name in your HTML as you want in your directive's scope you can just use the pass method. e.g.
scope: {
filterFunction: "&",
searchPlaceholder: "@",
pagedItems: "@",
clickFunction: "&",
classString: "@",
infoTemplate: "@template"
}
Upvotes: 1