将JSON对象作为参数传递给指令的链接函数

时间:2015-06-04 18:41:21

标签: angularjs

在一个指令中(让我们称之为购物篮),我有一个JSON对象(让我们称之为 fruit )在本地可用(即不需要$ http)。 fruit JSON对象相当复杂,每次都有动态数据。

该指令还动态生成一些html元素,每个元素都有自己的指令( apple banana ),然后将这些新元素编译到页面中:

myApp.directive("basket", function($compile) {
    return {
      link: function(scope, element) {

        var html = '';

        var fruits = ['apple', 'banana'];
        for (var i = 0; i < fruits.length; i++) {
          var fruit = {
            name: fruits[i],
            /* ... plus many other complex properties/objects/arrays ... */
          };
          html += '<div ' + fruits[i] + '=""></div>';
        }

        // Compile element.
        var linkFn = $compile(html);
        var content = linkFn(scope);
        element.append(content);

      }
    };
});

生成的html看起来像这样:

<div basket="">
  <div apple="">...</div>
  <div banana="">...</div>
</div>

如何将 fruit JSON对象传递到 apple banana 指令链接函数作为参数?

例如,我希望能够这样做:

myApp.directive("apple", function($compile) {
    return {
      link: function(scope, element, fruit) {

        // Build some custom html about an apple...
        var html = fruit.name;
        html += other_apple_related_stuff(fruit);

        // Compile element.
        var linkFn = $compile(html);
        var content = linkFn($scope);
        $element.append(content);

      }
    };
});

myApp.directive("banana", function($compile) {
    return {
      link: function(scope, element, fruit) {

        // Build some custom html about an banana...
        var html = fruit.name;
        html += other_banana_related_stuff(fruit);

        // Compile element.
        var linkFn = $compile(html);
        var content = linkFn($scope);
        $element.append(content);

      }
    };
});

尽管 apple 香蕉指令相似,但它们有足够的不同,我希望将它们的实现分隔为多个文件。

我知道我可以将 fruit JSON对象放在 $ scope 中,然后在 apple 香蕉指令。

但我真的希望将这个大型 fruit JSON对象作为参数提供给每个指令的链接函数。

解决

感谢@Awolf的演示代码,我能够分叉代码并获得所需的输出:https://jsfiddle.net/tyler_frankenstein/7cyLgscj/2/

1 个答案:

答案 0 :(得分:1)

如果我理解它是正确的。您可以使用服务并将其注入每个指令。 然后,您可以在每个指令中使用相同的JSON。

请查看下面的演示以及此fiddle

angular.module('myApp', [])
    .factory('fruitService', fruits)
    .directive('basket', basket)
    .directive('banana', banana)
    .directive('apple', apple);

function basket($compile, fruitService) {
    var ddo = {
        restrict: 'E',
        link: function (scope, element, attrs) {
            var html = '';

            var fruits = ['apple', 'banana'];
            
            for (var i = 0; i < fruits.length; i++) {
                var fruit = {
                    name: fruits[i],
                    /* ... plus many other complex properties/objects/arrays ... */
                };
                fruitService.pushFruits(fruit);
                html += '<div ' + fruits[i] + '=""></div>';
            }

            // Compile element.
            var linkFn = $compile(html);
            var content = linkFn(scope);
            element.append(content);
        }
    };

    return ddo;
}

basket.$inject = ['$compile', 'fruitService'];

function banana(fruitService) {
    return {
        template: '<p>banana</p><pre>{{fruits|json}}</pre>',
        link: function (scope, element, attrs) {
            console.log('banana', fruitService.getFruits());
            scope.fruits = fruitService.getFruits();
        }
    };
}

banana.$inject = ['fruitService'];

function apple(fruitService) {
    return {
        template: '<p>apple</p><pre>{{ctrl.fruits|json}}</pre>',
        controller: function ($scope) {
            // could be also the link method
            console.log('apple', fruitService.getFruits());
            this.fruits = fruitService.getFruits();
        },
        controllerAs: 'ctrl'
    };
}

apple.$inject = ['fruitService'];

function fruits() {
    return {
        fruits: [],
        pushFruits: function (newFruits) {
            this.fruits.push(newFruits);
        },
        getFruits: function () {
            return this.fruits;
        }
    };
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
    <basket></basket>
</div>