2

I'm new in angular and I'm trying to connect two isolated directives under the same controller. My project is about a product store; the first directive shows all available products in a list with a button, the second shows the information with details. Workflow should be this: when I click on the button of a product the detail information should be reloaded with the content of the choosen product.

I think I've done all the conections needed, but it still doesn't work, when I click the button nothing happens... Here are my declarations:

  • Main.html

    <div ng-controller="ProductController as productCtrl">
    <product-list data=productCtrl.productList></product-list>
    <product-details title={{productCtrl.activeProduct.title}} img={{productCtrl.activeProduct.imgSrc}} activator="productCtrl.setActiveProduct(p)"></product-details>
    <div>
    
  • ProductList.js

    'use strict'
    
    angular.module('angularTestAppApp')
      .directive("productList", function(){
        return {
          restrict: 'E',
          scope:{
            data: "=",
            function: "&activator"
          },
          templateUrl: 'views/ProductList.html'
        }
      });
    
  • ProductList.html

    <table class="table">
        <thead>
          <tr>
            <th></th>
            <th>Name</th>
            <th>Price</th>
            <th></th>
          </tr>
        </thead>
        <tbody>
          <tr ng-repeat="product in data">
            <th scope="row">
              <button class="btn btn-info glyphicon glyphicon-play" ng-click='function(product)'></button>
            </th>
            <td>{{product.title}}</td>
            <td>{{product.price | currency}}</td>
            <td>
              <img ng-src={{product.imgSrc}} width=15%></img>
            </td>
          </tr>
        </tbody>
      </table>
    
  • ProductController.js

    'use stricts'
    
    angular.module('angularTestAppApp')
      .controller('ProductController', function(productListService) {
    
        ...
    
        this.activeProduct = {
          "title": "Hymn for the Weekend",
          "imgSrc": "images/hymn.jpg",
          "price": "2"
        };
    
        this.setActiveProduct = function(p) {
          this.activeProduct = p;
          console.log('Active product ' + this.activeProduct);
        }
    
      });
    

Any idea?

Thanks for all :)!

EDIT: The problems were: - 1: The argument was in the wrong directive. - 2: I was writing bad the function, to set parameters you need to bind the data by this way:

    ng-click='function({product:product})'

Instead of 

    ng-click='function(product)'

Calling in the HTML directive by this way:

    <product-list data=productCtrl.productList activator="productCtrl.setActiveProduct(product)"></product-list>

Thanks for your help :).

3
  • Are you using a product-details directive? Can you post a sample code for that directive? Commented Apr 6, 2016 at 9:07
  • 1
    function is a reserved keyword and your productDetails directive is missing. Is it possible to create a fiddle? Commented Apr 6, 2016 at 9:07
  • Sorry, the problem was that I was setting the argument in the weong directive and writting bad the argument of the function. Thanks for reply! :) Commented Apr 6, 2016 at 10:29

1 Answer 1

2

There are 2 issues,

  • You are not passing function="expression" to the production-list directive
  • The & expression works on the scope, so the function must be defined in the scope

'use strict';
angular.module('angularTestAppApp', [])
angular.module('angularTestAppApp')
  .directive("productList", function() {
    return {
      restrict: 'E',
      scope: {
        data: "=",
        function: "&activator"
      },
      template: '<table class="table"><thead><tr><th></th><th>Name</th><th>Price</th><th></th></tr></thead><tbody><tr ng-repeat="product in data"><th scope="row"><button class="btn btn-info glyphicon glyphicon-play" ng-click="function({product:product})"></button></th><td>{{product.title}}</td><td>{{product.price | currency}}</td><td><img ng-src={{product.imgSrc}} width=15%></img></td></tr></tbody></table>'
    }
  });

angular.module('angularTestAppApp')
  .controller('ProductController', function($scope) {

    this.productList = [{
      title: 1,
      price: 1
    }, {
      title: 2,
      price: 2
    }];

    this.activeProduct = {
      "title": "Hymn for the Weekend",
      "imgSrc": "images/hymn.jpg",
      "price": "2"
    };

    var ctrl = this;
    $scope.setActiveProduct = function(p) {
      ctrl.activeProduct = p;
      console.log('Active product ' + ctrl.activeProduct, ctrl);
    }

  });
<link href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/css/bootstrap.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="angularTestAppApp">
  <div ng-controller="ProductController as productCtrl">
    <product-list data="productCtrl.productList" activator="setActiveProduct(product)"></product-list>
    <pre>{{productCtrl.activeProduct}}</pre>
    <product-details title={{productCtrl.activeProduct.title}} img={{productCtrl.activeProduct.imgSrc}} activator="productCtrl.setActiveProduct(p)"></product-details>
  </div>
</div>

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

1 Comment

Oh my god! The first issue is like a joke, I was setting the parameter in the wrong directive! (sorry for that). I didn't understand very well why do you need to set the function of the controller in the $scope, if I do that the function is never fired, however if I set it to the controller everything works fine :). The problem was that when I set the parameter to the function in the HTML the format was wrong, here is what I modified: function({product:product}) Being "product" the parameter in the top HTML (activator="productCtrl.setActiveProduct(product)">). Thanks for your help :D!

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.