locked
Calling factory function from a directive with binding tag angularjs RRS feed

  • Question

  • User2108892867 posted

    Hello everyone, I am trying to call a factory function from a directive like this: 

    <ul>
    <li data-ng-repeat="person in form.people">
     <div class="form-tag" get-data-fn="form.test(person.name)"></div>
    </li>
    </ul>

    Here is my factory and directive code:

    angular.module('form.services', [])
      .factory('peopleFactory', function() {
        var factory = {};
    
        factory.person = function(name) {
          var people = {
            john: {
              firstName: "John",
              lastName: "Smith",
              id: 123,
              tag: "<div>{{person.firstName}} is a doctor and his id is {{person.id}}</div>" +
                "<h1>{{person.lastName}}</h1>"
            },
            sam: {
              firstName: "Sam",
              lastName: "Cole",
              id: 456,
              tag: "<div>{{person.firstName}} has a different text</div>" +
                "<h1>{{person.lastName}}</h1>"
            },
            roy: {
              firstName: "Will",
              lastName: "Kan",
              id: 789,
              tag: "<h4>Some text about this person named {{person.firstName}} {{person.lastName}}</h4>"
            }
          };
    
          return person[name];
        };
    
    
        return factory;
      })
      .directive("formTag", function() {
        return {
          restrict: 'CA',
          scope: {
            getDataFn: '&'
          },
          template: '{{getDataFn().tag}}'
        }
      })

    And here is my js code to call the function above:

    angular
      .module("MyApp", ['form.services'])
      .controller("formController", ['$scope', 'peopleFactory', formController]);
    
    function formController($scope, peopleFactory) {
      var form = this;
    
      form.people = ['john', 'sam', 'roy']
    
      form.test = function(name) {
        var person = peopleFactory.person(name);
        return person;
      }
    }

    When I loaded this, the binding part doesn't work. It just displayed <div>{{person.firstName}} is a doctor and his id is {{person.id}}</div>. How could I bind this? Here is the plunker I have set up:

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

    Thanks. 

    Wednesday, September 26, 2018 4:43 AM

All replies

  • User61956409 posted

    Hi asplearning,

    It seems that you'd like to render dynamic html in the view via a custom directive, you can refer to the following sample code, which works for me.

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <title></title>
        <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>
    </head>
    <body ng-app="plunker" ng-controller="Ctrl">
        <ul>
            <li data-ng-repeat="person in people" class="ng-binding">
                <div class="change-it" get-data-fn="test(person)"></div>
            </li>
        </ul>
    </body>
    </html>
    <script>
        var app = angular.module('plunker', []);
    
        app.controller('Ctrl', function ($scope, peopleFactory) {
    
            $scope.people = ['john', 'sam', 'roy'];
    
            $scope.test = function (name) {
                var person = peopleFactory.person(name);
                return person;
            }
        });
    
        app.factory('peopleFactory', function () {
            var factory = {};
    
            factory.person = function (name) {
                var people = {
                    john: {
                        firstName: "John",
                        lastName: "Smith",
                        id: 123,
                        tag: "<div>John is a doctor and his id is 123</div>" +
                            "<h1>Smith</h1>"
                    },
                    sam: {
                        firstName: "Sam",
                        lastName: "Cole",
                        id: 456,
                        tag: "<div>Sam has a different text</div>" +
                            "<h1>Cole</h1>"
                    },
                    roy: {
                        firstName: "Will",
                        lastName: "Kan",
                        id: 789,
                        tag: "<h4>Some text about this person named Will Kan</h4>"
                    }
                };
                console.log(people[name]);
                return people[name];
            };
    
            return factory;
        });
    
        app.filter('sce', function ($sce) {
            return function (val) {
                return $sce.trustAsHtml(val);
            };
        });
    
        app.directive('changeIt', function ($compile) {
            return {
                restrict: 'CA',
                scope: { getDataFn: '&' },
                //template: '{{getDataFn().tag}}'
                template: '<div ng-bind-html="getDataFn().tag | sce"></div>'
            }
        }); 
    </script>

    Test Result:

    With Regards,

    Fei Han

    Thursday, September 27, 2018 7:42 AM
  • User2108892867 posted

    Hello Fei Han, thanks for your reply. Is it possible to do some binding on the fly when the tag is loaded? The sample code is just an example but I actually have some dynamic properties that I need to bind on the fly. 

    Thanks

    Thursday, September 27, 2018 9:11 PM
  • User2108892867 posted

    Anybody please? 

    Thanks

    Tuesday, October 2, 2018 2:13 AM